提交 557357e8 编写于 作者: A Alexey Milovidov

Better [#CLICKHOUSE-2].

上级 1a6cb298
......@@ -133,11 +133,11 @@ endif ()
#endif ()
if (CMAKE_VERSION VERSION_LESS "3.8.0")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++1z")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
else ()
set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CXX_FLAGS_INTERNAL_COMPILER "-std=gnu++1z")
set (CXX_FLAGS_INTERNAL_COMPILER "-std=c++1z")
endif ()
set (CMAKE_BUILD_COLOR_MAKEFILE ON)
......
......@@ -33,7 +33,7 @@ START_HEADERS=$(echo \
# Опция -mcx16 для того, чтобы выбиралось больше заголовочных файлов (с запасом).
# The latter options are the same that are added while building packages.
for src_file in $(echo | $CLANG -M -xc++ -std=gnu++1z -Wall -Werror -msse4 -mcx16 -mpopcnt -O3 -g -fPIC -fstack-protector -D_FORTIFY_SOURCE=2 \
for src_file in $(echo | $CLANG -M -xc++ -std=c++1z -Wall -Werror -msse4 -mcx16 -mpopcnt -O3 -g -fPIC -fstack-protector -D_FORTIFY_SOURCE=2 \
$(cat "$BUILD_PATH/include_directories.txt") \
$(echo $START_HEADERS | sed -r -e 's/[^ ]+/-include \0/g') \
- |
......
......@@ -607,10 +607,10 @@ Platform
#. We write code for specific platform. But other things equal cross platform and portable code is preferred.
#. Language is C++17. GNU extensions can be used if necessary.
#. Language is C++17.
#. Compiler is gcc. As of April 2017 version 6.3 is used. It is also compilable with clang 4.
Standard library from gcc is used.
#. Compiler is gcc. As of December 2017 version 7.2 is used. It is also compilable with clang 5.
Standard library is used (libstdc++ or libc++).
#. OS - Linux Ubuntu, not older than Precise.
......
......@@ -131,7 +131,7 @@
25. При использовании шаблонных типов, пишите `using` (кроме, возможно, простейших случаев).
То есть, параметры шаблона указываются только в `using` и затем не повторяются в коде.
`using` может быть объявлен локально, например, внутри функции.
```
......@@ -159,7 +159,7 @@
29. Для не очень большого класса/структуры, можно не отделять объявления методов от реализации.
Аналогично для маленьких методов в любых классах/структурах.
Для шаблонных классов/структур, лучше не отделять объявления методов от реализации (так как иначе они всё равно должны быть определены в той же единице трансляции).
30. Не обязательно умещать код по ширине в 80 символов. Можно в 140.
31. Всегда используйте префиксный инкремент/декремент, если постфиксный не нужен.
......@@ -342,7 +342,7 @@
};
```
15. Все имена - по английски. Транслит с русского использовать нельзя.
```
не Stroka
```
......@@ -351,9 +351,9 @@
`AST`, `SQL`.
Не `NVDH` (что-то неведомое)
Сокращения в виде обрезанного слова можно использовать, только если такое сокращение является широко используемым.
Впрочем, сокращения также можно использовать, если расшифровка находится рядом в комментарии.
17. Имена файлов с исходниками на C++ должны иметь расширение только .cpp. Заголовочные файлы - только .h.
......@@ -368,7 +368,7 @@
В прикладном коде следует делать так, что память освобождается каким-либо объектом, который владеет ей.
Примеры:
- проще всего разместить объект на стеке, или сделать его членом другого класса.
- для большого количества маленьких объектов используйте контейнеры.
- для автоматического освобождения маленького количества объектов, выделенных на куче, используйте shared_ptr/unique_ptr.
......@@ -379,11 +379,11 @@
3. Обработка ошибок.
Используйте исключения. В большинстве случаев, нужно только кидать исключения, а ловить - не нужно (потому что RAII).
В программах offline обработки данных, зачастую, можно не ловить исключения.
В серверах, обрабатывающих пользовательские запросы, как правило, достаточно ловить исключения на самом верху обработчика соединения.
В функциях потока, следует ловить и запоминать все исключения, чтобы выкинуть их в основном потоке после join.
```cpp
......@@ -401,9 +401,9 @@
```
Ни в коем случае не «проглатывайте» исключения без разбора. Ни в коем случае, не превращайте все исключения без разбора в сообщения в логе.
Не `catch (...) {}`.
Если вам нужно проигнорировать какие-то исключения, то игнорируйте только конкретные, а остальные - кидайте обратно.
```cpp
......@@ -431,9 +431,9 @@
5. Исключения, вылетающие из деструкторов.
Использовать не рекомендуется, но допустимо.
Используйте следующие варианты:
- Сделайте функцию (done() или finalize()), которая позволяет заранее выполнить всю работу, в процессе которой может возникнуть исключение. Если эта функция была вызвана, то затем в деструкторе не должно возникать исключений.
- Слишком сложную работу (например, отправку данных по сети) можно вообще не делать в деструкторе, рассчитывая, что пользователь заранее позовёт метод для завершения работы.
- Если в деструкторе возникло исключение, желательно не "проглатывать" его, а вывести информацию в лог (если в этом месте доступен логгер).
......@@ -458,21 +458,21 @@
В программах offline обработки данных:
- cначала добейтесь более-менее максимальной производительности на одном процессорном ядре, потом можно распараллеливать код, но только если есть необходимость.
В программах - серверах:
- используйте пул потоков для обработки запросов. На данный момент, у нас не было задач, в которых была бы необходимость использовать userspace context switching.
Fork для распараллеливания не используется.
8. Синхронизация потоков.
Часто можно сделать так, чтобы отдельные потоки писали данные в разные ячейки памяти (лучше - в разные кэш-линии), и не использовать синхронизацию потоков (кроме joinAll).
Если синхронизация нужна, то в большинстве случаев, достаточно использовать mutex под lock_guard-ом.
В остальных случаях, используйте системные примитивы синхронизации. Не используйте busy wait.
Атомарные операции можно использовать только в простейших случаях.
Не нужно писать самостоятельно lock-free структуры данных, если вы не являетесь экспертом.
9. Ссылки и указатели.
......@@ -480,9 +480,9 @@
10. const.
Используйте константные ссылки, указатели на константу, const_iterator, константные методы.
Считайте, что const - вариант написания «по умолчанию», а отсутствие const - только при необходимости.
Для переменных, передающихся по значению, использовать const обычно не имеет смысла.
11. unsigned.
......@@ -490,19 +490,19 @@
12. Числовые типы.
Используйте типы UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, а также size_t, ssize_t, ptrdiff_t.
Не используйте для чисел типы signed/unsigned long, long long, short; signed char, unsigned char, а также char.
13. Передача аргументов.
Сложные значения передавайте по ссылке (включая std::string).
Если функция захватывает владение объектом, созданным на куче, то сделайте типом аргумента shared_ptr или unique_ptr.
14. Возврат значений.
В большинстве случаев, просто возвращайте значение с помощью return. Не пишите [return std::move(res)]{.strike}.
Если внутри функции создаётся объект на куче и отдаётся наружу, то возвращайте shared_ptr или unique_ptr.
В некоторых редких случаях, может потребоваться возвращать значение через аргумент функции. В этом случае, аргументом будет ссылка.
```cpp
......@@ -519,21 +519,21 @@
15. namespace.
Для прикладного кода отдельный namespace использовать не нужно.
Для маленьких библиотек - не требуется.
Для не совсем маленьких библиотек - поместите всё в namespace.
Внутри библиотеки в .h файле можно использовать namespace detail для деталей реализации, не нужных прикладному коду.
В .cpp файле можно использовать static или анонимный namespace для скрытия символов.
Также, namespace можно использовать для enum, чтобы соответствующие имена не попали во внешний namespace (но лучше использовать enum class).
16. Отложенная инициализация.
Обычно, если для инициализации требуются аргументы, то не пишите конструктор по умопчанию.
Если потом вам потребовалась отложенная инициализация, то вы можете дописать конструктор по умолчанию (который создаст объект с некорректным состоянием). Или, для небольшого количества объектов, можно использовать shared_ptr/unique_ptr.
```cpp
......@@ -551,26 +551,26 @@
19. Логгирование.
См. примеры везде в коде.
Перед коммитом, удалите всё бессмысленное и отладочное логгирование, и другие виды отладочного вывода.
Не должно быть логгирования на каждую итерацию внутреннего цикла, даже уровня Trace.
При любом уровне логгирования, логи должно быть возможно читать.
Логгирование следует использовать, в основном, только в прикладном коде.
Сообщения в логе должны быть написаны на английском языке.
Желательно, чтобы лог был понятен системному администратору.
Не нужно писать ругательства в лог.
В логе используется кодировка UTF-8. Изредка можно использовать в логе не-ASCII символы.
20. Ввод-вывод.
Во внутренних циклах (в критичных по производительности участках программы) нельзя использовать iostreams (в том числе, ни в коем случае не используйте stringstream).
Вместо этого используйте библиотеку DB/IO.
21. Дата и время.
......@@ -584,7 +584,7 @@
23. using.
using namespace не используется.
using что-то конкретное - можно. Лучше локально - внутри класса или функции.
24. Не нужно использовать trailing return type для функций, если в этом нет необходимости.
......@@ -596,9 +596,9 @@
```cpp
auto s = std::string{"Hello"};
```
Надо так:
```cpp
std::string s = "Hello";
std::string s{"Hello"};
......@@ -617,11 +617,11 @@
Хотя, при прочих равных условиях, предпочитается более-менее кроссплатформенный или легко портируемый код.
2. Язык - C++17. Возможно использование расширений GNU при необходимости.
2. Язык - C++17.
3. Компилятор - gcc. На данный момент (апрель 2017), код собирается версией 6.3. (Также код может быть собран clang 4)
3. Компилятор - gcc. На данный момент (декабрь 2017), код собирается версией 7.2. (Также код может быть собран clang 5)
Используется стандартная библиотека от gcc.
Используется стандартная библиотека (реализация libstdc++ или libc++).
4. ОС - Linux Ubuntu, не более старая, чем Precise.
......@@ -649,7 +649,7 @@
8. Коммитьте как можно чаще, в том числе и не рабочий код.
Для этого следует использовать бранчи.
Если ваш код в master-е ещё не собирается, перед push-ем - исключите его из сборки, также вы будете должны его доработать или удалить в течение нескольких дней.
9. Для нетривиальных изменений, используются бранчи. Следует загружать бранчи на сервер.
10. Ненужный код удаляется из исходников.
......@@ -681,17 +681,17 @@
1. Явное указание std:: для типов из stddef.h.
Рекомендуется не указывать. То есть, рекомендуется писать size_t вместо std::size_t - потому что это короче.
Но при желании, вы можете всё-таки приписать std:: - такой вариант тоже допустим.
2. Явное указание std:: для функций из стандартной библиотеки C.
Не рекомендуется. То есть, пишите memcpy вместо std::memcpy.
Причина - существуют похожие нестандартные функции, например, memmem. Мы можем использовать и изредка используем эти функции. Эти функции отсутствуют в namespace std.
Если вы везде напишете std::memcpy вместо memcpy, то будет неудобно смотреться memmem без std::.
Тем не менее, указывать std:: тоже допустимо, если так больше нравится.
3. Использование функций из C при наличии аналогов в стандартной библиотеке C++.
......@@ -735,4 +735,4 @@
const & RangesInDataParts ranges,
size_t limit)
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册