SlideShare une entreprise Scribd logo
1  sur  63
C++ Core Guidelines
Сергей Зубков
Morgan Stanley
С благодарностями Бьярне Страуструпу
Zubkov - Guidelines - C++ Russia 2017 2
О чем это?
(и почему волнуется Rust?)
Что такое "Современный C++"?
• C++11, C++14, C++17, несколько технических
спецификаций (концепции, интервалы, сеть,
модули, корутины, и пр), множество новых
возможностей и подходов.
Правильный вопрос:
• Как выглядит хороший современный С++?
• Как он будет выглядеть в ближайшем будущем?
• Как сделать его доступным рядовым программистам, а
не экспертам из комитета?
Zubkov - Guidelines - C++ Russia 2017 3
Что такое "Современный C++"?
• Многие программисты (включая экспертов!)
• Пишут в устаревшем стиле, игнорируя 20+ лет прогресса и опыта
• Пишут в чужеродном стиле (как Java или как C)
• Путаются в деталях
• Наслаждаются деталями
- Доктор, мне больно, когда я так делаю!
- Так не делайте так!
Zubkov - Guidelines - C++ Russia 2017 4
Что такое "Современный C++"?
Как сделать современный C++ проще и доступнее?
• прямо сейчас!
• не создавая новый язык
• сохраняя совместимость
• cохраняя экспрессивную мощь
• сохраняя производительность
Три составные части нашего подхода:
Набор правил + Библиотека + Статический анализ
Zubkov - Guidelines - C++ Russia 2017 5
Набор правил + Библиотека + Статический анализ
В каждой компании уже есть набор правил для C++!
Типичные правила:
• Создаются в начале проекта/компании
• без опыта и наугад
• Устаревают
• обуза для пользователей / технический долг
• Узко специализированы
• применяются за пределами специализации
• Недостаточно объяснены
• требуют слепого подчинения или эксперта под рукой
• Носят запретительный характер
Zubkov - Guidelines - C++ Russia 2017 6
Набор правил + Библиотека + Статический анализ
Чем отличаются Core Guidelines?
• Современный С++ (и С++ ближайшего будущего)
• Каким вы хотите видеть новый код через пять лет?
• Предписания, не запрещения
• Плюс разъяснения достаточные для использования в обучении
• Не привязаны к конкретной компании
• Гитхаб под эгидой isocpp.org
• Анализаторы разрабатываются разными компаниями
• Центральные (“Core”)
• Компании и проекты могут включать и выключать группы правил (“профили”) и
дописывать/удалять индивидуальные правила по вкусу – и это уже реальность.
Zubkov - Guidelines - C++ Russia 2017 7
Набор правил + Библиотека + Статический анализ
Чем отличаются Core Guidelines?
Не только и не столько стиль программирования, в главные цели входят:
• Статическая типобезопасность
• Нет возможности обратиться к T как U
• Безопасность работы с памятью
• Нет доступа за пределы массива
• Гарантии времени жизни всех объектов
• Нет висячих указателей и ссылок
• Ресурсобезопасность
• Нет утечек ресурсов, включая утечки памяти
• В будущем - больше
Zubkov - Guidelines - C++ Russia 2017 8
Набор правил + Библиотека + Статический анализ
Не цели
• не минимальные
• не ортогональные
• не книга (и не учебник)
• не руководство по модернизации кода (хотя есть правила модернизации)
• не детальный список особых случаев (для этого есть стандарт)
• не подмножество языка (не теряет экспрессивность)
• не идеальные (сообщайте об ошибках)
Zubkov - Guidelines - C++ Russia 2017 9
Набор правил + Библиотека + Статический анализ
Правил много!
• Не все программисты смогут включить все правила
• Как минимум, не сразу: постепенная интеграция жизненно необходима
• Многим потребуется больше правил
• Для нетипичных ситуаций
• Наша цель: центральные правила (Core Guidelines)
• Правила для большинства
• Переход количества в качество:
• Нет утечкам ресурсов
• Нет висячим указателям
• Нет нарушениям типобезопасности
Zubkov - Guidelines - C++ Russia 2017 10
Набор правил + Библиотека + Статический анализ
“подмножество надмножества”
(изначально разработан для доменно-специфичных языков на основе С++)
• Нельзя запрещать без альтернатив
• Альтернатива – стандартная библиотека
• С дополнениями (потому что “прямо сейчас”)
Guidelines Support Library (https://github.com/Microsoft/GSL)
• Для необычных ситуаций – с собственными дополнениями (MyCompany Support Library)
• Авторы библиотеки могут пользоваться грязными/сложными/опасными
возможностями языка – для того они и существуют.
Цель: безопасная работа с массивами (без дополнительных проверок!)
Надмножество (библиотека): std::string_view, gsl::span, gsl::zstring
Подмножество (правила): не превращать массивы в указатели
не делать арифметику на указателях
не передавать указатель и размер
Zubkov - Guidelines - C++ Russia 2017 11
C++
GSL
Нельзя:
Стандартная
библиотека
Можно:
Набор правил + Библиотека + Статический анализ
Microsoft Visual Studio
LLVM Clang
Некоторые другие, близкие по духу, статические анализаторы также планируют
включить правила из Code Guidelines (например IFS Cevelop)
Zubkov - Guidelines - C++ Russia 2017 12
Набор правил + Библиотека + Статический анализ
Zubkov - Guidelines - C++ Russia 2017 13
Сколько ошибок в
этой программе?
Набор правил + Библиотека + Статический анализ
Zubkov - Guidelines - C++ Russia 2017 14
Набор правил + Библиотека + Статический анализ
Zubkov - Guidelines - C++ Russia 2017 15
Набор правил + Библиотека + Статический анализ
Zubkov - Guidelines - C++ Russia 2017 16
Набор правил
github.com/isocpp/CppCoreGuidelines
Zubkov - Guidelines - C++ Russia 2017 17
github.com/isocpp/CppCoreGuidelines
• 2014-2015: Morgan Stanley + Microsoft + ЦЕРН
• 13 сентября 2015 (CppCon15): на гитхабе
Принимайте участие!
Zubkov - Guidelines - C++ Russia 2017 18
Цели Core Guidelines
• Сделать целые классы ошибок невозможными
• Меньше времени в отладчике, меньше шансов для крахов и хаков
• Сделать невозможными утечки ресурсов
• Без потери производительности
• Сделать невозможными висячие указатели
• Без потери производительности
• Сделать невозможным выход за границы массива
• Без потери производительности
• Упростить
• Простой код проще поддерживать и проще преподавать
• Подальше от темных мест и экзотических приемов
• Программировать как эксперты
Zubkov - Guidelines - C++ Russia 2017 19
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Zubkov - Guidelines - C++ Russia 2017 20
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Смысл кода должен быть понятен из кода:
комментарии не компилируются!
change_speed(double s); // Что за double?
change_speed(2.3); // В каких единицах?
change_speed(Speed s); // ok: это новая скорость
change_speed(23_m / 10s); // ok: метры в секунду
change_speed(2.3); // ошибка компиляции
Zubkov - Guidelines - C++ Russia 2017 21
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Пишите на стандартном С++, запрещайте нестандартные
расширения языка. Когда они действительно нужны,
изолируйте от остального кода.
Для gcc и clang “-std=c++14” недостаточно!
Расширения отключаются ”-pedantic-errors”
Zubkov - Guidelines - C++ Russia 2017 22
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Код должен выражать цели, не средства
Плохо:
int i = 0;
while (i < v.size()) { /* работа с v[i] */ }
Лучше:
for (const auto& x : v) { /* работа с x */ } // порядок важен
for_each(par, v, [](int x) { /* работа с x */ }); // порядок неважен
Zubkov - Guidelines - C++ Russia 2017 23
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Статическая типобезопасность
(см также type safety profile)
std::variant вместо union
Нет преобразований массивов в указатели (см gsl::span)
Нет сужающих конверсий (см gsl::narrow_cast)
Нет кастов (явных приведений типов)
Никаких void* Zubkov - Guidelines - C++ Russia 2017 24
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Предпочитайте ошибки компиляции проверкам в коде
static_assert(sizeof(void*)==8, “64 bit required”);
static_assert(sizeof(VMPage) == PAGESIZE);
f(gsl::span<int>); // а не f(int*, int)
Zubkov - Guidelines - C++ Russia 2017 25
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Если нельзя сделать ошибкой компиляции, должна быть
возможность проверить в коде.
Контракты (см gsl_assert)
Исключения
Валидность указателя проверить невозможно!Zubkov - Guidelines - C++ Russia 2017 26
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Проверяйте ошибки как можно раньше
(идеально в конструкторах, чтобы не повторять проверки)
std::vector и gsl::span вместо массивов
gsl::not_null вместо указателей
Структуры и классы вместо строк
Zubkov - Guidelines - C++ Russia 2017 27
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Никаких утечек ресурсов – памяти, файлов, и т п.
RAII классы (std::vector, std::fstream, std::lock_guard)
std::make_unique/std::make_shared
gsl::finally
Никаких malloc/free/new/delete/strdup/fopen
Zubkov - Guidelines - C++ Russia 2017 28
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Эффективно используйте и память и процессор: это все-таки C++!
Всегда планируйте как минимум возможность оптимизации
(Per.7). Избегайте лишнего кода (знайте, что есть в библиотеках),
лишних проверок (см P.7 и правила об инвариантах),
избыточные структуры данных (от ненужных связных списков до
плохо упакованных структур).
Zubkov - Guidelines - C++ Russia 2017 29
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Предпочитайте константы и неизменяемые данные
Все что может быть constexpr или const, должно быть:
объекты,
методы,
ссылки и указатели.
(исключения – объекты, возвращаемые из функций)
Zubkov - Guidelines - C++ Russia 2017 30
Секция P: Философия
• P.1: Express ideas directly in code
• P.2: Write in ISO Standard C++
• P.3: Express intent
• P.4: Ideally, a program should be statically type safe
• P.5: Prefer compile-time checking to run-time checking
• P.6: What cannot be checked at compile time should be checkable at run time
• P.7: Catch run-time errors early
• P.8: Don't leak any resources
• P.9: Don't waste time or space
• P.10: Prefer immutable data to mutable data
• P.11: Encapsulate messy constructs, rather than spreading through the code
Прячьте грязный код в библиотеках за удобными интерфейсами,
и больше им не пользуйтесь.
Это опять принцип “подмножество надмножества”
в стандартной библиотеке масса примеров: union внутри
std::variant, указатели внутри std::vector и пр
Zubkov - Guidelines - C++ Russia 2017 31
Интерфейсы (фрагмент)
• I.1: Make interfaces explicit
• I.2: Avoid global variables
• I.3: Avoid singletons
• I.4: Make interfaces precisely and strongly typed
• I.5: State preconditions (if any)
• I.7: State postconditions
• I.10: Use exceptions to signal a failure to perform a required task
• I.11: Never transfer ownership by a raw pointer (T*)
• I.12: Declare a pointer that must not be null as not_null
• I.13: Do not pass an array as a single pointer
• I.24: Avoid adjacent unrelated parameters of the same type
• I.26: If you want a cross-compiler ABI, use a C-style subset
Zubkov - Guidelines - C++ Russia 2017 32
Интерфейсы (фрагмент)
• I.1: Make interfaces explicit
• I.2: Avoid global variables
• I.3: Avoid singletons
• I.4: Make interfaces precisely and strongly typed
• I.5: State preconditions (if any)
• I.7: State postconditions
• I.10: Use exceptions to signal a failure to perform a required task
• I.11: Never transfer ownership by a raw pointer (T*)
• I.12: Declare a pointer that must not be null as not_null
• I.13: Do not pass an array as a single pointer
• I.24: Avoid adjacent unrelated parameters of the same type
• I.26: If you want a cross-compiler ABI, use a C-style subset
Zubkov - Guidelines - C++ Russia 2017 33
Передача массива в виде одного указателя и даже в виде пары
аргументов (указатель и размер, указатели на начало и конец) –
источник ошибок. Размер массива не должен быть отделен от
самого массива.
Плохо:
void copy_n(const T* p, T* q, int n); // копия из [p:p+n) в [q:q+n)
Лучше:
void copy(gsl::span<const T> r, gsl::span<T> r2); // копия из r в r2
Интерфейсы (фрагмент)
• I.1: Make interfaces explicit
• I.2: Avoid global variables
• I.3: Avoid singletons
• I.4: Make interfaces precisely and strongly typed
• I.5: State preconditions (if any)
• I.7: State postconditions
• I.10: Use exceptions to signal a failure to perform a required task
• I.11: Never transfer ownership by a raw pointer (T*)
• I.12: Declare a pointer that must not be null as not_null
• I.13: Do not pass an array as a single pointer
• I.24: Avoid adjacent unrelated parameters of the same type
• I.26: If you want a cross-compiler ABI, use a C-style subset
Zubkov - Guidelines - C++ Russia 2017 34
Функции сообщают от ошибках исключениями
(“ошибка” – невозможность выполнить свою функцию,
гарантировать постусловие или восстановить инвариант).
int printf(const char* ...); // Плохо: возвращает код ошибки
template <class F, class ...Args>
explicit thread(F&& f, Args&&... args); // Лучше: бросает system_error
Функции (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 35
• F.22: Use T* or owner<T*> or a smart pointer to designate a single object
• F.23: Use a not_null<T> to indicate "null" is not a valid value
• F.24: Use a span<T> or a span_p<T> to designate a half-open sequence
• F.25: Use a zstring or a not_null<zstring> to designate a C-style string
• F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed
• F.27: Use a shared_ptr<T> to share ownership
• F.44: Return a T& when copy is undesirable and "returning no object" isn't an option
• F.45: Don't return a T&&
• F.50: Use a lambda when a function won't do (to capture local variables, or to write a
local function)
• F.51: Where there is a choice, prefer default arguments over overloading
• F.52: Prefer capturing by reference in lambdas that will be used locally
Функции (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 36
• F.22: Use T* or owner<T*> or a smart pointer to designate a single object
• F.23: Use a not_null<T> to indicate "null" is not a valid value
• F.24: Use a span<T> or a span_p<T> to designate a half-open sequence
• F.25: Use a zstring or a not_null<zstring> to designate a C-style string
• F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed
• F.27: Use a shared_ptr<T> to share ownership
• F.44: Return a T& when copy is undesirable and "returning no object" isn't an option
• F.45: Don't return a T&&
• F.50: Use a lambda when a function won't do (to capture local variables, or to write a
local function)
• F.51: Where there is a choice, prefer default arguments over overloading
• F.52: Prefer capturing by reference in lambdas that will be used locally
• gsl::not_null<T> (где T = U*, std::unique_ptr<U>, std::shared_ptr<U>),
гарантирует что T - не нулевой указатель. (см также I.12)
• Если параметр not_null, проверка в вызываемой функции не нужна
• Eсли результат not_null, проверка в вызывающей функции не нужна
int f(const int* p, gsl::not_null<const int*> q)
{
if(q) return *q; // бессмысленная проверка (F.23)
return *p; // опасный код! Голый указатель может быть нулевым (F.60)
}
Функции (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 37
• F.22: Use T* or owner<T*> or a smart pointer to designate a single object
• F.23: Use a not_null<T> to indicate "null" is not a valid value
• F.24: Use a span<T> or a span_p<T> to designate a half-open sequence
• F.25: Use a zstring or a not_null<zstring> to designate a C-style string
• F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed
• F.27: Use a shared_ptr<T> to share ownership
• F.44: Return a T& when copy is undesirable and "returning no object" isn't an option
• F.45: Don't return a T&&
• F.50: Use a lambda when a function won't do (to capture local variables, or to write a
local function)
• F.51: Where there is a choice, prefer default arguments over overloading
• F.52: Prefer capturing by reference in lambdas that will be used locally
• Если есть возможность, пользуйтеся аргументами по умолчанию
вместо перегрузки функций: перегрузка – для похожих операций
над аргументами разных типов.
• Плохо: нет гарантии что код этих двух функций идентичен
void print(const string& s); // формат по умолчанию
void print(const string& s, format f);
• Лучше:
void print(const string& s, format f = {});
Параметры и аргументы (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 38
Классы (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 39
• C.2: Use class if the class has an invariant; use struct if the data members can vary
independently
• C.4: Make a function a member only if it needs direct access to the representation of a
class
• C.5: Place helper functions in the same namespace as the class they support
• C.20: If you can avoid defining any default operations, do
• C.21: If you define or =delete any default operation, define or =delete them all
• C.35: A base class with a virtual function needs a virtual destructor
• C.36: A destructor may not fail
• C.40: Define a constructor if a class has an invariant
• C.41: A constructor should create a fully initialized object
• C.42: If a constructor cannot construct a valid object, throw an exception
• C.43: Ensure that a class has a default constructor
• C.45: Prefer to use member initializers
Классы (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 40
• C.2: Use class if the class has an invariant; use struct if the data members can vary
independently
• C.4: Make a function a member only if it needs direct access to the representation of a
class
• C.5: Place helper functions in the same namespace as the class they support
• C.20: If you can avoid defining any default operations, do
• C.21: If you define or =delete any default operation, define or =delete them all
• C.35: A base class with a virtual function needs a virtual destructor
• C.36: A destructor may not fail
• C.40: Define a constructor if a class has an invariant
• C.41: A constructor should create a fully initialized object
• C.42: If a constructor cannot construct a valid object, throw an exception
• C.43: Ensure that a class has a default constructor
• C.45: Prefer to use member initializers
• Конструктор устанавливает инвариант, функции-члены считают, что
инвариант гарантирован.
• Если данные можно менять напрямую, инвариант невозможен.
• struct Desc {
string left; // left и right могут меняться независимо друг от друга
string right; // инварианта нет
};
• class IntArray {
public:
// конструкторы, деструктор и пр
private:
gsl::owner<int*> beg; // инвариант: beg указывает на массив
int* end; // инвариант: end указывает на конец массива
};
Классы (фрагмент)
Zubkov - Guidelines - C++ Russia 2017 41
• C.2: Use class if the class has an invariant; use struct if the data members can vary
independently
• C.4: Make a function a member only if it needs direct access to the representation of a
class
• C.5: Place helper functions in the same namespace as the class they support
• C.20: If you can avoid defining any default operations, do
• C.21: If you define or =delete any default operation, define or =delete them all
• C.35: A base class with a virtual function needs a virtual destructor
• C.36: A destructor may not fail
• C.40: Define a constructor if a class has an invariant
• C.41: A constructor should create a fully initialized object
• C.42: If a constructor cannot construct a valid object, throw an exception
• C.43: Ensure that a class has a default constructor
• C.45: Prefer to use member initializers
• Стандартные конструкторы
• Делают возможным массивы и упрощают код
• Требуются для все регулярных типов
• Предоставляют состояние, которое можно использовать в
операциях перемещения
• class Date {
public:
Date(Day dd, Month mm, Year yyyy);
Date() = default; // См C.45
private:
int day = 1;
int month = 1;
int year = 1970;
};
std::vector<Date> vd(1000);
Наследование (фрагмент)
• C.121: If a base class is used as an interface, make it a pure abstract class
• C.126: An abstract class typically doesn't need a constructor
• C.127: A class with a virtual function should have a virtual or protected destructor
• C.128: Virtual functions should specify exactly one of virtual, override, or final
• C.131: Avoid trivial getters and setters
• C.132: Don't make a function virtual without reason
• C.133: Avoid protected data
• C.138: Create an overload set for a derived class and its bases with using
• C.140: Do not provide different default arguments for a virtual function and an overrider
• C.146: Use dynamic_cast where class hierarchy navigation is unavoidable
• C.147: Use dynamic_cast to a reference type when failure to find the required class is
considered an error
• C.152: Never assign a pointer to an array of derived class objects to a pointer to its base
Zubkov - Guidelines - C++ Russia 2017 42
Наследование (фрагмент)
• C.121: If a base class is used as an interface, make it a pure abstract class
• C.126: An abstract class typically doesn't need a constructor
• C.127: A class with a virtual function should have a virtual or protected destructor
• C.128: Virtual functions should specify exactly one of virtual, override, or final
• C.131: Avoid trivial getters and setters
• C.132: Don't make a function virtual without reason
• C.133: Avoid protected data
• C.138: Create an overload set for a derived class and its bases with using
• C.140: Do not provide different default arguments for a virtual function and an overrider
• C.146: Use dynamic_cast where class hierarchy navigation is unavoidable
• C.147: Use dynamic_cast to a reference type when failure to find the required class is
considered an error
• C.152: Never assign a pointer to an array of derived class objects to a pointer to its base
Zubkov - Guidelines - C++ Russia 2017 43
• Если в классе есть виртуальная функция, деструктор должет быть
виртуальными и доступным или невиртуальным и защищенным
• (удаление полиморфного класса с невиртуальным деструктором
через базовый указатель – неопределенное поведение)
• struct B {
virtual int f() = 0;
// деструктор по умолчанию доступный и невиртуальный
};
struct D : B { string s {"default"}; };
void use() {
std::unique_ptr<B> p = std::make_unique<D>();
} // Undefined Behavior (как минимум утечка памяти из-за строки)
Наследование (фрагмент)
• C.121: If a base class is used as an interface, make it a pure abstract class
• C.126: An abstract class typically doesn't need a constructor
• C.127: A class with a virtual function should have a virtual or protected destructor
• C.128: Virtual functions should specify exactly one of virtual, override, or final
• C.131: Avoid trivial getters and setters
• C.132: Don't make a function virtual without reason
• C.133: Avoid protected data
• C.138: Create an overload set for a derived class and its bases with using
• C.140: Do not provide different default arguments for a virtual function and an overrider
• C.146: Use dynamic_cast where class hierarchy navigation is unavoidable
• C.147: Use dynamic_cast to a reference type when failure to find the required class is
considered an error
• C.152: Never assign a pointer to an array of derived class objects to a pointer to its base
Zubkov - Guidelines - C++ Russia 2017 44
• Тривиальные геттеры и сеттеры не нужны
• // Плохо:
• class Point {
int x;
public:
int get_x() const { return x; }
void set_x(int xx) { x = xx; }
};
• // Лучше
• struct Point {
int x = 0;
}
Шаблоны (фрагмент)
• T.5: Combine generic and OO techniques to amplify their strengths, not their
costs
• T.61+T.62: Don’t over-parametrize
• T.64: Use specialization to provide alternative implementations of class templates
• T.65: Use tag dispatch to provide alternative implementations of functions
• T.67: Use specialization to provide alternative implementations for irregular types
• T.69: Inside a template, don't make an unqualified nonmember function call
unless you intend it to be a customization point
• #749 avoid recursion in variadic templates
• T.122: Use templates (usually template aliases) to compute types at compile time
• T.123: Use constexpr functions to compute values at compile time
• T.144: Don't specialize function templates
Zubkov - Guidelines - C++ Russia 2017 45
Шаблоны (фрагмент)
• T.5: Combine generic and OO techniques to amplify their strengths, not their
costs
• T.61+T.62: Don’t over-parametrize
• T.64: Use specialization to provide alternative implementations of class templates
• T.65: Use tag dispatch to provide alternative implementations of functions
• T.67: Use specialization to provide alternative implementations for irregular types
• T.69: Inside a template, don't make an unqualified nonmember function call
unless you intend it to be a customization point
• #749 avoid recursion in variadic templates
• T.122: Use templates (usually template aliases) to compute types at compile time
• T.123: Use constexpr functions to compute values at compile time
• T.144: Don't specialize function templates
Zubkov - Guidelines - C++ Russia 2017 46
• Излишняя параметризация – источник раздувания кода (даже
если компилятор поддерживает ICF).
• Если член шаблона зависит только от N параметров, он должен
быть в базовом классе, зависящем только от этих N параметров.
• // Плохо:
• template<typename T> class Foo { enum { v1, v2 }; … };
• // Лучше:
• struct Foo_base { enum { v1, v2 }; … };
template<typename T> class Foo : public Foo_base { … };
Шаблоны (фрагмент)
• T.5: Combine generic and OO techniques to amplify their strengths, not their
costs
• T.61+T.62: Don’t over-parametrize
• T.64: Use specialization to provide alternative implementations of class templates
• T.65: Use tag dispatch to provide alternative implementations of functions
• T.67: Use specialization to provide alternative implementations for irregular types
• T.69: Inside a template, don't make an unqualified nonmember function call
unless you intend it to be a customization point
• #749 avoid recursion in variadic templates
• T.122: Use templates (usually template aliases) to compute types at compile time
• T.123: Use constexpr functions to compute values at compile time
• T.144: Don't specialize function templates
Zubkov - Guidelines - C++ Russia 2017 47
• Рекурсия в шаблонном коде тормозит компиляцию. Ее можно
избежать при помощи fold expressions, constexpr функций,
std::index_sequence (std::invoke и т п) и просто pack expansions.
• // Плохо:
• template<class T> void pbv(vector<T>& v) {}
template<class T, class H, class... Ts>
void pbv(vector<T>& v, H&& h, Ts&&... Ts) {
v.push_back(h);
pbv(v, ts...);
}
• // Лучше
template<class T, class... Ts) void pbv(vector<T>& v, Ts&&... Ts) {
(v.push_back(ts), ...);
}
Профили
• Профиль – набор правил ставящих целью обеспечить конкретную
гарантию.
• Type safety (типобезопасность)
• Bounds safety (безопасность работы с массивами)
• Lifetime safety (гарантии времени жизни объектов)
• В будущем – arithmetic, concurrency, noexcept, noalloc, etc.
Zubkov - Guidelines - C++ Russia 2017 48
Профиль типобезопасности
• P.4: Ideally, a program should be statically type safe
• C.183: Don't use a union for type punning
• Type.1: Don't use reinterpret_cast
• Type.2: Don't use static_cast downcasts. Use dynamic_cast instead
• Type.3: Don't use const_cast to cast away const (i.e., at all)
• Type.4: Don't use C-style (T)expression casts that would perform a
static_cast downcast, const_cast, or reinterpret_cast
• Type.5: Don't use a variable before it has been initialized
• Type.6: Always initialize a member variable
Zubkov - Guidelines - C++ Russia 2017 49
Массивы и Указатели (Bounds Profile)
• ES.55: Avoid the need for range checking
• Bounds.1: Don't use pointer arithmetic. Use span instead.
• Bounds.2: Only index into arrays using constant expressions.
• Bounds.3: No array-to-pointer decay.
• Bounds.4: Don't use standard library functions and types that are not
bounds-checked.
Zubkov - Guidelines - C++ Russia 2017 50
Контроль времени жизни объектов
(Lifetime Profile)
1. У каждого объекта есть только один владелец
2. На объект могут ссылаться много ссылок/указателей
3. Никакая ссылка/указатель не может пережить владельца
• Правила для обычной функции:
• Не показывать ссылку/указатель на локальную переменную тому кто вызвал
• Ссылка/указатель переданная как аргумент может быть возвращена
• Указатель от new может быть возвращен если мы сообщим что этот указатель – владелец
int* f(int* p) {
int x = 4;
return &x; // Ошибка
return new int{7}; // OK, только надо отметить что это - владелец
return p; // OK: откуда пришло, туда и вернется
}
Zubkov - Guidelines - C++ Russia 2017 51
Контроль времени жизни объектов
(Lifetime Profile)
• Как отмечать владельцев?
• Предпочтительно: std::unique_ptr, std::vector, std::map, std::shared_ptr,
• На низком уровне (например внутри std::vector<T>): gsl::owner<T>
template<class T> using owner = T;
• Этот низкоуровневый owner существует только на уровне системы типов и
статического анализа, в компилированном коде он неотличим от T
vector<int*> f(int* p)
{
owner<int*> q = new int{7};
vector<int*> res = {p, q}; // OK: копия q – не владелец
return res; // Ошибка: владелец должен быть возвращен или удален
}
Zubkov - Guidelines - C++ Russia 2017 52
Правила будущего
• T.10/I.9: Specify concepts for all template arguments
• T.11: Whenever possible use standard concepts
• T.12: Prefer concept names over auto for local variables
• T.13: Prefer the shorthand notation for simple, single-type argument concepts
• T.20: Avoid "concepts" without meaningful semantics
• T.21: Require a complete set of operations for a concept
• T.22: Specify axioms for concepts
• T.23: Differentiate a refined concept from its more general case by adding new use patterns
• T.24: Use tag classes or traits to differentiate concepts that differ only in semantics
• T.25: Avoid complementary constraints
• T.26: Prefer to define concepts in terms of use-patterns rather than simple syntax
• T.30+31: Use !C<T> / C1<T> || C2<T> sparingly
• I.6+8: Prefer Expects() for expressing preconditions/ Ensures() for expressing postconditions
Zubkov - Guidelines - C++ Russia 2017 53
См также http://stroustrup.com/good_concepts.pdf
Не-правила и мифы
• NR.1: Don't: All declarations should be at the top of a function
• NR.2: Don't: Have only a single return-statement in a function
• NR.3: Don't: Don't use exceptions
• NR.4: Don't: Place each class declaration in its own source file
• NR.5: Don't: Don't do substantive work in a constructor; instead use
two-phase initialization
• NR.6: Don't: Place all cleanup actions at the end of a function and
goto exit
• NR.7: Don't: Make all data members protected
Zubkov - Guidelines - C++ Russia 2017 54
Слишком много правил?
• Эти правила для всех:
• Новичков, экспертов, библиотек, системщиков, обычных и необычных
приложений
• Никто не предлагает выучить все эти правила!
• Никто не предлагает даже прочитать все эти правила!
• Подавляющее большинство правил предназначено для
анализаторов:
• Анализ отметит возможное нарушение и покажет какое правило
прочитать:
•
Zubkov - Guidelines - C++ Russia 2017 55
Мы хотим хороший современный С++
• “Мы” значит “вы”
• это не под силу одному человеку или одной компании
• Каким вы хотите видеть код через 5 лет?
• “Таким же как и сегодня” – не ответ
• Модернизировать много кода – нелегко
• Если ясна цель – можно к ней двигаться
• Не все согласны с тем как выглядит хороший С++
• Код не должен выглядеть одинакого
• Но должно быть общее ядро
• Нужно обсуждать и применять правила и анализаторы
• Помогайте!
• Нужны правила, анализ, комментарии, редакторы
https://github.com/isocpp/CppCoreGuidelines
Zubkov - Guidelines - C++ Russia 2017 56
Zubkov - Guidelines - C++ Russia 2017 57
extras
Zubkov - Guidelines - C++ Russia 2017 58
Обработка ошибок (фрагмент)
• E.1: Develop an error-handling strategy early in a design
• E.2: Throw an exception to signal that a function can't perform its assigned task
• E.3: Use exceptions for error handling only
• E.5: Let a constructor establish an invariant, and throw if it cannot
• E.12: Use noexcept when exiting a function because of a throw is impossible or unacceptable
• E.13: Never throw while being the direct owner of an object
• E.14: Use purpose-designed user-defined types as exceptions (not built-in types)
• E.15: Catch exceptions from a hierarchy by reference
• E.16: Destructors, deallocation, and swap must never fail
• E.17: Don't try to catch every exception in every function
• E.18: Minimize the use of explicit try/catch
• E.19: Use a final_action object to express cleanup if no suitable resource handle is available
Zubkov - Guidelines - C++ Russia 2017 59
Многозадачность (избранное)
• CP.4: Think in terms of tasks, rather than threads
• CP.8: Don't try to use volatile for synchronization
• CP.20+21: Use RAII, never plain lock()/unlock() / Use std::lock() to acquire multiple mutexes
• CP.22: Never call unknown code while holding a lock (e.g., a callback)
• CP.23+24: Think of a joining thread as a scoped container / a detached thread as a global container
• CP.25+26: Prefer gsl::raii_thread / gsl::detached_thread
• CP.31: Pass small amounts of data between threads by value, rather than by reference or pointer
• CP.32: To share ownership between unrelated threads use shared_ptr
• CP.42: Don't wait without a condition
• CP.50: Define a mutex together with the data it protects
• Use algorithms that are designed for parallelism, not algorithms with unnecessary dependency on linear
evaluation
• CP.60: Use a future to return a value from a concurrent task
• CP.100: Don't use lock-free programming unless you absolutely have to
Zubkov - Guidelines - C++ Russia 2017 60
Управление ресурсами
• R.1: Manage resources automatically using resource handles and RAII
• R.3: A raw pointer (a T*) is non-owning
• R.4: A raw reference (a T&) is non-owning
• R.5: Prefer scoped objects
• R.10+11: Avoid malloc() and free() / Avoid calling new and delete explicitly
• R.12: Immediately give the result of an explicit resource allocation to a manager object
• R.13: Perform at most one explicit resource allocation in a single expression statement
• R.15: Always overload matched allocation/deallocation pairs
• R.20: Use unique_ptr or shared_ptr to represent ownership
• R.21: Prefer unique_ptr over shared_ptr unless you need to share ownership
• R.22+23: Use make_shared() to make shared_ptrs / make_unique() to make unique_ptrs
• R.30: Take smart pointers as parameters only to explicitly express lifetime semantics
Zubkov - Guidelines - C++ Russia 2017 61
Выражения и инструкции (избранное)
• ES.5: Keep scopes small
• ES.11: Use auto to avoid redundant repetition of type names
• ES.20: Always initialize an object
• ES.21+22: Don't introduce a variable (or constant) before you need to use it / until you have a
value to initialize it with
• ES.23: Prefer the {}-initializer syntax
• ES.24: Use a unique_ptr<T> to hold pointers in code that may throw
• ES.26: Don't use a variable for two unrelated purposes
• ES.28: Use lambdas for complex initialization, especially of const variables
• ES.30+31: Don't use macros for program text manipulation / for constants or "functions"
• ES.45: Avoid narrowing conversions
• ES.48: Avoid casts
• ES.56: Avoid std::move() in application code
• ES.63: Don't slice
Zubkov - Guidelines - C++ Russia 2017 62
const
• P.10: Prefer immutable data to mutable data
• ES.25: Declare an object const or constexpr unless you want to modify its value
later on
• ES.50: Don't cast away const
• F.4: If a function may have to be evaluated at compile time, declare it constexpr
• R.6: Avoid non-const global variables
• Con.1: By default, make objects immutable
• Con.2: By default, make member functions const
• Con.3: By default, pass pointers and references to consts
• Con.4: Use const to define objects with values that do not change after
construction
• Con.5: Use constexpr for values that can be computed at compile time
Zubkov - Guidelines - C++ Russia 2017 63

Contenu connexe

Tendances

SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекPython Meetup
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1m2rus
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)Alexander Gornik
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФПAlexander Granin
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоCodeFest
 
C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееGetDev.NET
 
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)Ontico
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Yauheni Akhotnikau
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Stas Vyschepan
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp
 

Tendances (20)

SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван Панченко
 
C# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущееC# 5.0. Взгляд в будущее
C# 5.0. Взгляд в будущее
 
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
 
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный PythonWebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp 2016: Python.Максим Климишин.Типизированный Python
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
 

En vedette

Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++NextSergey Platonov
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3Platonov Sergey
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Mikhail Matrosov
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерSergey Platonov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11corehard_by
 
C++Now Trip Report
C++Now Trip ReportC++Now Trip Report
C++Now Trip Reportcorehard_by
 
Battle: BDD vs notBDD
Battle: BDD vs notBDDBattle: BDD vs notBDD
Battle: BDD vs notBDDCOMAQA.BY
 
Restinio - header-only http and websocket server
Restinio - header-only http and websocket serverRestinio - header-only http and websocket server
Restinio - header-only http and websocket servercorehard_by
 
Actors for fun and profit
Actors for fun and profitActors for fun and profit
Actors for fun and profitcorehard_by
 
Ускоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборокУскоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборокcorehard_by
 
Analysis and interpretation of monitoring data
Analysis and interpretation of monitoring dataAnalysis and interpretation of monitoring data
Analysis and interpretation of monitoring datacorehard_by
 
(Не)чёткий поиск
(Не)чёткий поиск(Не)чёткий поиск
(Не)чёткий поискcorehard_by
 
C++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse EngineeringC++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse Engineeringcorehard_by
 
MxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency ManagerMxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency Managercorehard_by
 
C++ в играх, больших и не очень
C++ в играх, больших и не оченьC++ в играх, больших и не очень
C++ в играх, больших и не оченьcorehard_by
 
The beast is becoming functional
The beast is becoming functionalThe beast is becoming functional
The beast is becoming functionalcorehard_by
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаcorehard_by
 

En vedette (20)

Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11Mixing C++ & Python II: Pybind11
Mixing C++ & Python II: Pybind11
 
C++Now Trip Report
C++Now Trip ReportC++Now Trip Report
C++Now Trip Report
 
Battle: BDD vs notBDD
Battle: BDD vs notBDDBattle: BDD vs notBDD
Battle: BDD vs notBDD
 
Benchmark it
Benchmark itBenchmark it
Benchmark it
 
Restinio - header-only http and websocket server
Restinio - header-only http and websocket serverRestinio - header-only http and websocket server
Restinio - header-only http and websocket server
 
Actors for fun and profit
Actors for fun and profitActors for fun and profit
Actors for fun and profit
 
Ускоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборокУскоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборок
 
Analysis and interpretation of monitoring data
Analysis and interpretation of monitoring dataAnalysis and interpretation of monitoring data
Analysis and interpretation of monitoring data
 
(Не)чёткий поиск
(Не)чёткий поиск(Не)чёткий поиск
(Не)чёткий поиск
 
C++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse EngineeringC++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse Engineering
 
MxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency ManagerMxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency Manager
 
C++ в играх, больших и не очень
C++ в играх, больших и не оченьC++ в играх, больших и не очень
C++ в играх, больших и не очень
 
The beast is becoming functional
The beast is becoming functionalThe beast is becoming functional
The beast is becoming functional
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 

Similaire à C++ Core Guidelines

Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Ontico
 
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...HappyDev
 
"Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно..."Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно...it-people
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseAlexander Granin
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовYandex
 
Алексей Лустин. Непрерывная проверка качества кода.
Алексей Лустин. Непрерывная проверка качества кода.Алексей Лустин. Непрерывная проверка качества кода.
Алексей Лустин. Непрерывная проверка качества кода.ScrumTrek
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrusAlex Chistyakov
 
Workflow: работа над проектом в Яндексе
Workflow: работа над проектом в ЯндексеWorkflow: работа над проектом в Яндексе
Workflow: работа над проектом в ЯндексеDenis Chistyakov
 
Денис Чистяков: Workflow. Работа над проектом в Яндексе
Денис Чистяков: Workflow. Работа над проектом в ЯндексеДенис Чистяков: Workflow. Работа над проектом в Яндексе
Денис Чистяков: Workflow. Работа над проектом в ЯндексеYandex
 
Юрий Василевский "Автоматизация в XCode"
Юрий Василевский "Автоматизация в XCode"Юрий Василевский "Автоматизация в XCode"
Юрий Василевский "Автоматизация в XCode"Yandex
 
Юрий Василевский «Автоматизация в XCode»
Юрий Василевский «Автоматизация в XCode»Юрий Василевский «Автоматизация в XCode»
Юрий Василевский «Автоматизация в XCode»Yandex
 
Devconf 2011 - PHP - Как разрабатывается фреймворк Yii
Devconf 2011 - PHP - Как разрабатывается фреймворк YiiDevconf 2011 - PHP - Как разрабатывается фреймворк Yii
Devconf 2011 - PHP - Как разрабатывается фреймворк YiiAlexander Makarov
 
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...IT-Portfolio
 
Проходим тест Джоэла
Проходим тест ДжоэлаПроходим тест Джоэла
Проходим тест Джоэла0leGG
 
Лучшие практики на практике
Лучшие практики на практикеЛучшие практики на практике
Лучшие практики на практикеDenis Tuchin
 

Similaire à C++ Core Guidelines (20)

Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
 
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
Виталий Шибаев - Креативный менеджмент глазами разработчика: как выжить в agi...
 
"Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно..."Девопс - это не только для программистов. Практические примеры из жизни одно...
"Девопс - это не только для программистов. Практические примеры из жизни одно...
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом Enterprise
 
DevOps для 1С
DevOps для 1СDevOps для 1С
DevOps для 1С
 
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав БахмутовПлюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
Плюсы и минусы Go для разработчиков на C++, Вячеслав Бахмутов
 
Алексей Лустин. Непрерывная проверка качества кода.
Алексей Лустин. Непрерывная проверка качества кода.Алексей Лустин. Непрерывная проверка качества кода.
Алексей Лустин. Непрерывная проверка качества кода.
 
Daemons In Web on #devrus
Daemons In Web on #devrusDaemons In Web on #devrus
Daemons In Web on #devrus
 
Workflow: работа над проектом в Яндексе
Workflow: работа над проектом в ЯндексеWorkflow: работа над проектом в Яндексе
Workflow: работа над проектом в Яндексе
 
Денис Чистяков: Workflow. Работа над проектом в Яндексе
Денис Чистяков: Workflow. Работа над проектом в ЯндексеДенис Чистяков: Workflow. Работа над проектом в Яндексе
Денис Чистяков: Workflow. Работа над проектом в Яндексе
 
Как разраба
Как разрабаКак разраба
Как разраба
 
Юрий Василевский "Автоматизация в XCode"
Юрий Василевский "Автоматизация в XCode"Юрий Василевский "Автоматизация в XCode"
Юрий Василевский "Автоматизация в XCode"
 
Юрий Василевский «Автоматизация в XCode»
Юрий Василевский «Автоматизация в XCode»Юрий Василевский «Автоматизация в XCode»
Юрий Василевский «Автоматизация в XCode»
 
Devconf 2011 - PHP - Как разрабатывается фреймворк Yii
Devconf 2011 - PHP - Как разрабатывается фреймворк YiiDevconf 2011 - PHP - Как разрабатывается фреймворк Yii
Devconf 2011 - PHP - Как разрабатывается фреймворк Yii
 
Ryazan
RyazanRyazan
Ryazan
 
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Управление ок...
 
Little Service in 2h
Little Service in 2hLittle Service in 2h
Little Service in 2h
 
Проходим тест Джоэла
Проходим тест ДжоэлаПроходим тест Джоэла
Проходим тест Джоэла
 
Лучшие практики на практике
Лучшие практики на практикеЛучшие практики на практике
Лучшие практики на практике
 

C++ Core Guidelines

  • 1. C++ Core Guidelines Сергей Зубков Morgan Stanley С благодарностями Бьярне Страуструпу
  • 2. Zubkov - Guidelines - C++ Russia 2017 2 О чем это? (и почему волнуется Rust?)
  • 3. Что такое "Современный C++"? • C++11, C++14, C++17, несколько технических спецификаций (концепции, интервалы, сеть, модули, корутины, и пр), множество новых возможностей и подходов. Правильный вопрос: • Как выглядит хороший современный С++? • Как он будет выглядеть в ближайшем будущем? • Как сделать его доступным рядовым программистам, а не экспертам из комитета? Zubkov - Guidelines - C++ Russia 2017 3
  • 4. Что такое "Современный C++"? • Многие программисты (включая экспертов!) • Пишут в устаревшем стиле, игнорируя 20+ лет прогресса и опыта • Пишут в чужеродном стиле (как Java или как C) • Путаются в деталях • Наслаждаются деталями - Доктор, мне больно, когда я так делаю! - Так не делайте так! Zubkov - Guidelines - C++ Russia 2017 4
  • 5. Что такое "Современный C++"? Как сделать современный C++ проще и доступнее? • прямо сейчас! • не создавая новый язык • сохраняя совместимость • cохраняя экспрессивную мощь • сохраняя производительность Три составные части нашего подхода: Набор правил + Библиотека + Статический анализ Zubkov - Guidelines - C++ Russia 2017 5
  • 6. Набор правил + Библиотека + Статический анализ В каждой компании уже есть набор правил для C++! Типичные правила: • Создаются в начале проекта/компании • без опыта и наугад • Устаревают • обуза для пользователей / технический долг • Узко специализированы • применяются за пределами специализации • Недостаточно объяснены • требуют слепого подчинения или эксперта под рукой • Носят запретительный характер Zubkov - Guidelines - C++ Russia 2017 6
  • 7. Набор правил + Библиотека + Статический анализ Чем отличаются Core Guidelines? • Современный С++ (и С++ ближайшего будущего) • Каким вы хотите видеть новый код через пять лет? • Предписания, не запрещения • Плюс разъяснения достаточные для использования в обучении • Не привязаны к конкретной компании • Гитхаб под эгидой isocpp.org • Анализаторы разрабатываются разными компаниями • Центральные (“Core”) • Компании и проекты могут включать и выключать группы правил (“профили”) и дописывать/удалять индивидуальные правила по вкусу – и это уже реальность. Zubkov - Guidelines - C++ Russia 2017 7
  • 8. Набор правил + Библиотека + Статический анализ Чем отличаются Core Guidelines? Не только и не столько стиль программирования, в главные цели входят: • Статическая типобезопасность • Нет возможности обратиться к T как U • Безопасность работы с памятью • Нет доступа за пределы массива • Гарантии времени жизни всех объектов • Нет висячих указателей и ссылок • Ресурсобезопасность • Нет утечек ресурсов, включая утечки памяти • В будущем - больше Zubkov - Guidelines - C++ Russia 2017 8
  • 9. Набор правил + Библиотека + Статический анализ Не цели • не минимальные • не ортогональные • не книга (и не учебник) • не руководство по модернизации кода (хотя есть правила модернизации) • не детальный список особых случаев (для этого есть стандарт) • не подмножество языка (не теряет экспрессивность) • не идеальные (сообщайте об ошибках) Zubkov - Guidelines - C++ Russia 2017 9
  • 10. Набор правил + Библиотека + Статический анализ Правил много! • Не все программисты смогут включить все правила • Как минимум, не сразу: постепенная интеграция жизненно необходима • Многим потребуется больше правил • Для нетипичных ситуаций • Наша цель: центральные правила (Core Guidelines) • Правила для большинства • Переход количества в качество: • Нет утечкам ресурсов • Нет висячим указателям • Нет нарушениям типобезопасности Zubkov - Guidelines - C++ Russia 2017 10
  • 11. Набор правил + Библиотека + Статический анализ “подмножество надмножества” (изначально разработан для доменно-специфичных языков на основе С++) • Нельзя запрещать без альтернатив • Альтернатива – стандартная библиотека • С дополнениями (потому что “прямо сейчас”) Guidelines Support Library (https://github.com/Microsoft/GSL) • Для необычных ситуаций – с собственными дополнениями (MyCompany Support Library) • Авторы библиотеки могут пользоваться грязными/сложными/опасными возможностями языка – для того они и существуют. Цель: безопасная работа с массивами (без дополнительных проверок!) Надмножество (библиотека): std::string_view, gsl::span, gsl::zstring Подмножество (правила): не превращать массивы в указатели не делать арифметику на указателях не передавать указатель и размер Zubkov - Guidelines - C++ Russia 2017 11 C++ GSL Нельзя: Стандартная библиотека Можно:
  • 12. Набор правил + Библиотека + Статический анализ Microsoft Visual Studio LLVM Clang Некоторые другие, близкие по духу, статические анализаторы также планируют включить правила из Code Guidelines (например IFS Cevelop) Zubkov - Guidelines - C++ Russia 2017 12
  • 13. Набор правил + Библиотека + Статический анализ Zubkov - Guidelines - C++ Russia 2017 13 Сколько ошибок в этой программе?
  • 14. Набор правил + Библиотека + Статический анализ Zubkov - Guidelines - C++ Russia 2017 14
  • 15. Набор правил + Библиотека + Статический анализ Zubkov - Guidelines - C++ Russia 2017 15
  • 16. Набор правил + Библиотека + Статический анализ Zubkov - Guidelines - C++ Russia 2017 16
  • 18. github.com/isocpp/CppCoreGuidelines • 2014-2015: Morgan Stanley + Microsoft + ЦЕРН • 13 сентября 2015 (CppCon15): на гитхабе Принимайте участие! Zubkov - Guidelines - C++ Russia 2017 18
  • 19. Цели Core Guidelines • Сделать целые классы ошибок невозможными • Меньше времени в отладчике, меньше шансов для крахов и хаков • Сделать невозможными утечки ресурсов • Без потери производительности • Сделать невозможными висячие указатели • Без потери производительности • Сделать невозможным выход за границы массива • Без потери производительности • Упростить • Простой код проще поддерживать и проще преподавать • Подальше от темных мест и экзотических приемов • Программировать как эксперты Zubkov - Guidelines - C++ Russia 2017 19
  • 20. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Zubkov - Guidelines - C++ Russia 2017 20
  • 21. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Смысл кода должен быть понятен из кода: комментарии не компилируются! change_speed(double s); // Что за double? change_speed(2.3); // В каких единицах? change_speed(Speed s); // ok: это новая скорость change_speed(23_m / 10s); // ok: метры в секунду change_speed(2.3); // ошибка компиляции Zubkov - Guidelines - C++ Russia 2017 21
  • 22. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Пишите на стандартном С++, запрещайте нестандартные расширения языка. Когда они действительно нужны, изолируйте от остального кода. Для gcc и clang “-std=c++14” недостаточно! Расширения отключаются ”-pedantic-errors” Zubkov - Guidelines - C++ Russia 2017 22
  • 23. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Код должен выражать цели, не средства Плохо: int i = 0; while (i < v.size()) { /* работа с v[i] */ } Лучше: for (const auto& x : v) { /* работа с x */ } // порядок важен for_each(par, v, [](int x) { /* работа с x */ }); // порядок неважен Zubkov - Guidelines - C++ Russia 2017 23
  • 24. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Статическая типобезопасность (см также type safety profile) std::variant вместо union Нет преобразований массивов в указатели (см gsl::span) Нет сужающих конверсий (см gsl::narrow_cast) Нет кастов (явных приведений типов) Никаких void* Zubkov - Guidelines - C++ Russia 2017 24
  • 25. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Предпочитайте ошибки компиляции проверкам в коде static_assert(sizeof(void*)==8, “64 bit required”); static_assert(sizeof(VMPage) == PAGESIZE); f(gsl::span<int>); // а не f(int*, int) Zubkov - Guidelines - C++ Russia 2017 25
  • 26. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Если нельзя сделать ошибкой компиляции, должна быть возможность проверить в коде. Контракты (см gsl_assert) Исключения Валидность указателя проверить невозможно!Zubkov - Guidelines - C++ Russia 2017 26
  • 27. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Проверяйте ошибки как можно раньше (идеально в конструкторах, чтобы не повторять проверки) std::vector и gsl::span вместо массивов gsl::not_null вместо указателей Структуры и классы вместо строк Zubkov - Guidelines - C++ Russia 2017 27
  • 28. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Никаких утечек ресурсов – памяти, файлов, и т п. RAII классы (std::vector, std::fstream, std::lock_guard) std::make_unique/std::make_shared gsl::finally Никаких malloc/free/new/delete/strdup/fopen Zubkov - Guidelines - C++ Russia 2017 28
  • 29. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Эффективно используйте и память и процессор: это все-таки C++! Всегда планируйте как минимум возможность оптимизации (Per.7). Избегайте лишнего кода (знайте, что есть в библиотеках), лишних проверок (см P.7 и правила об инвариантах), избыточные структуры данных (от ненужных связных списков до плохо упакованных структур). Zubkov - Guidelines - C++ Russia 2017 29
  • 30. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Предпочитайте константы и неизменяемые данные Все что может быть constexpr или const, должно быть: объекты, методы, ссылки и указатели. (исключения – объекты, возвращаемые из функций) Zubkov - Guidelines - C++ Russia 2017 30
  • 31. Секция P: Философия • P.1: Express ideas directly in code • P.2: Write in ISO Standard C++ • P.3: Express intent • P.4: Ideally, a program should be statically type safe • P.5: Prefer compile-time checking to run-time checking • P.6: What cannot be checked at compile time should be checkable at run time • P.7: Catch run-time errors early • P.8: Don't leak any resources • P.9: Don't waste time or space • P.10: Prefer immutable data to mutable data • P.11: Encapsulate messy constructs, rather than spreading through the code Прячьте грязный код в библиотеках за удобными интерфейсами, и больше им не пользуйтесь. Это опять принцип “подмножество надмножества” в стандартной библиотеке масса примеров: union внутри std::variant, указатели внутри std::vector и пр Zubkov - Guidelines - C++ Russia 2017 31
  • 32. Интерфейсы (фрагмент) • I.1: Make interfaces explicit • I.2: Avoid global variables • I.3: Avoid singletons • I.4: Make interfaces precisely and strongly typed • I.5: State preconditions (if any) • I.7: State postconditions • I.10: Use exceptions to signal a failure to perform a required task • I.11: Never transfer ownership by a raw pointer (T*) • I.12: Declare a pointer that must not be null as not_null • I.13: Do not pass an array as a single pointer • I.24: Avoid adjacent unrelated parameters of the same type • I.26: If you want a cross-compiler ABI, use a C-style subset Zubkov - Guidelines - C++ Russia 2017 32
  • 33. Интерфейсы (фрагмент) • I.1: Make interfaces explicit • I.2: Avoid global variables • I.3: Avoid singletons • I.4: Make interfaces precisely and strongly typed • I.5: State preconditions (if any) • I.7: State postconditions • I.10: Use exceptions to signal a failure to perform a required task • I.11: Never transfer ownership by a raw pointer (T*) • I.12: Declare a pointer that must not be null as not_null • I.13: Do not pass an array as a single pointer • I.24: Avoid adjacent unrelated parameters of the same type • I.26: If you want a cross-compiler ABI, use a C-style subset Zubkov - Guidelines - C++ Russia 2017 33 Передача массива в виде одного указателя и даже в виде пары аргументов (указатель и размер, указатели на начало и конец) – источник ошибок. Размер массива не должен быть отделен от самого массива. Плохо: void copy_n(const T* p, T* q, int n); // копия из [p:p+n) в [q:q+n) Лучше: void copy(gsl::span<const T> r, gsl::span<T> r2); // копия из r в r2
  • 34. Интерфейсы (фрагмент) • I.1: Make interfaces explicit • I.2: Avoid global variables • I.3: Avoid singletons • I.4: Make interfaces precisely and strongly typed • I.5: State preconditions (if any) • I.7: State postconditions • I.10: Use exceptions to signal a failure to perform a required task • I.11: Never transfer ownership by a raw pointer (T*) • I.12: Declare a pointer that must not be null as not_null • I.13: Do not pass an array as a single pointer • I.24: Avoid adjacent unrelated parameters of the same type • I.26: If you want a cross-compiler ABI, use a C-style subset Zubkov - Guidelines - C++ Russia 2017 34 Функции сообщают от ошибках исключениями (“ошибка” – невозможность выполнить свою функцию, гарантировать постусловие или восстановить инвариант). int printf(const char* ...); // Плохо: возвращает код ошибки template <class F, class ...Args> explicit thread(F&& f, Args&&... args); // Лучше: бросает system_error
  • 35. Функции (фрагмент) Zubkov - Guidelines - C++ Russia 2017 35 • F.22: Use T* or owner<T*> or a smart pointer to designate a single object • F.23: Use a not_null<T> to indicate "null" is not a valid value • F.24: Use a span<T> or a span_p<T> to designate a half-open sequence • F.25: Use a zstring or a not_null<zstring> to designate a C-style string • F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed • F.27: Use a shared_ptr<T> to share ownership • F.44: Return a T& when copy is undesirable and "returning no object" isn't an option • F.45: Don't return a T&& • F.50: Use a lambda when a function won't do (to capture local variables, or to write a local function) • F.51: Where there is a choice, prefer default arguments over overloading • F.52: Prefer capturing by reference in lambdas that will be used locally
  • 36. Функции (фрагмент) Zubkov - Guidelines - C++ Russia 2017 36 • F.22: Use T* or owner<T*> or a smart pointer to designate a single object • F.23: Use a not_null<T> to indicate "null" is not a valid value • F.24: Use a span<T> or a span_p<T> to designate a half-open sequence • F.25: Use a zstring or a not_null<zstring> to designate a C-style string • F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed • F.27: Use a shared_ptr<T> to share ownership • F.44: Return a T& when copy is undesirable and "returning no object" isn't an option • F.45: Don't return a T&& • F.50: Use a lambda when a function won't do (to capture local variables, or to write a local function) • F.51: Where there is a choice, prefer default arguments over overloading • F.52: Prefer capturing by reference in lambdas that will be used locally • gsl::not_null<T> (где T = U*, std::unique_ptr<U>, std::shared_ptr<U>), гарантирует что T - не нулевой указатель. (см также I.12) • Если параметр not_null, проверка в вызываемой функции не нужна • Eсли результат not_null, проверка в вызывающей функции не нужна int f(const int* p, gsl::not_null<const int*> q) { if(q) return *q; // бессмысленная проверка (F.23) return *p; // опасный код! Голый указатель может быть нулевым (F.60) }
  • 37. Функции (фрагмент) Zubkov - Guidelines - C++ Russia 2017 37 • F.22: Use T* or owner<T*> or a smart pointer to designate a single object • F.23: Use a not_null<T> to indicate "null" is not a valid value • F.24: Use a span<T> or a span_p<T> to designate a half-open sequence • F.25: Use a zstring or a not_null<zstring> to designate a C-style string • F.26: Use a unique_ptr<T> to transfer ownership where a pointer is needed • F.27: Use a shared_ptr<T> to share ownership • F.44: Return a T& when copy is undesirable and "returning no object" isn't an option • F.45: Don't return a T&& • F.50: Use a lambda when a function won't do (to capture local variables, or to write a local function) • F.51: Where there is a choice, prefer default arguments over overloading • F.52: Prefer capturing by reference in lambdas that will be used locally • Если есть возможность, пользуйтеся аргументами по умолчанию вместо перегрузки функций: перегрузка – для похожих операций над аргументами разных типов. • Плохо: нет гарантии что код этих двух функций идентичен void print(const string& s); // формат по умолчанию void print(const string& s, format f); • Лучше: void print(const string& s, format f = {});
  • 38. Параметры и аргументы (фрагмент) Zubkov - Guidelines - C++ Russia 2017 38
  • 39. Классы (фрагмент) Zubkov - Guidelines - C++ Russia 2017 39 • C.2: Use class if the class has an invariant; use struct if the data members can vary independently • C.4: Make a function a member only if it needs direct access to the representation of a class • C.5: Place helper functions in the same namespace as the class they support • C.20: If you can avoid defining any default operations, do • C.21: If you define or =delete any default operation, define or =delete them all • C.35: A base class with a virtual function needs a virtual destructor • C.36: A destructor may not fail • C.40: Define a constructor if a class has an invariant • C.41: A constructor should create a fully initialized object • C.42: If a constructor cannot construct a valid object, throw an exception • C.43: Ensure that a class has a default constructor • C.45: Prefer to use member initializers
  • 40. Классы (фрагмент) Zubkov - Guidelines - C++ Russia 2017 40 • C.2: Use class if the class has an invariant; use struct if the data members can vary independently • C.4: Make a function a member only if it needs direct access to the representation of a class • C.5: Place helper functions in the same namespace as the class they support • C.20: If you can avoid defining any default operations, do • C.21: If you define or =delete any default operation, define or =delete them all • C.35: A base class with a virtual function needs a virtual destructor • C.36: A destructor may not fail • C.40: Define a constructor if a class has an invariant • C.41: A constructor should create a fully initialized object • C.42: If a constructor cannot construct a valid object, throw an exception • C.43: Ensure that a class has a default constructor • C.45: Prefer to use member initializers • Конструктор устанавливает инвариант, функции-члены считают, что инвариант гарантирован. • Если данные можно менять напрямую, инвариант невозможен. • struct Desc { string left; // left и right могут меняться независимо друг от друга string right; // инварианта нет }; • class IntArray { public: // конструкторы, деструктор и пр private: gsl::owner<int*> beg; // инвариант: beg указывает на массив int* end; // инвариант: end указывает на конец массива };
  • 41. Классы (фрагмент) Zubkov - Guidelines - C++ Russia 2017 41 • C.2: Use class if the class has an invariant; use struct if the data members can vary independently • C.4: Make a function a member only if it needs direct access to the representation of a class • C.5: Place helper functions in the same namespace as the class they support • C.20: If you can avoid defining any default operations, do • C.21: If you define or =delete any default operation, define or =delete them all • C.35: A base class with a virtual function needs a virtual destructor • C.36: A destructor may not fail • C.40: Define a constructor if a class has an invariant • C.41: A constructor should create a fully initialized object • C.42: If a constructor cannot construct a valid object, throw an exception • C.43: Ensure that a class has a default constructor • C.45: Prefer to use member initializers • Стандартные конструкторы • Делают возможным массивы и упрощают код • Требуются для все регулярных типов • Предоставляют состояние, которое можно использовать в операциях перемещения • class Date { public: Date(Day dd, Month mm, Year yyyy); Date() = default; // См C.45 private: int day = 1; int month = 1; int year = 1970; }; std::vector<Date> vd(1000);
  • 42. Наследование (фрагмент) • C.121: If a base class is used as an interface, make it a pure abstract class • C.126: An abstract class typically doesn't need a constructor • C.127: A class with a virtual function should have a virtual or protected destructor • C.128: Virtual functions should specify exactly one of virtual, override, or final • C.131: Avoid trivial getters and setters • C.132: Don't make a function virtual without reason • C.133: Avoid protected data • C.138: Create an overload set for a derived class and its bases with using • C.140: Do not provide different default arguments for a virtual function and an overrider • C.146: Use dynamic_cast where class hierarchy navigation is unavoidable • C.147: Use dynamic_cast to a reference type when failure to find the required class is considered an error • C.152: Never assign a pointer to an array of derived class objects to a pointer to its base Zubkov - Guidelines - C++ Russia 2017 42
  • 43. Наследование (фрагмент) • C.121: If a base class is used as an interface, make it a pure abstract class • C.126: An abstract class typically doesn't need a constructor • C.127: A class with a virtual function should have a virtual or protected destructor • C.128: Virtual functions should specify exactly one of virtual, override, or final • C.131: Avoid trivial getters and setters • C.132: Don't make a function virtual without reason • C.133: Avoid protected data • C.138: Create an overload set for a derived class and its bases with using • C.140: Do not provide different default arguments for a virtual function and an overrider • C.146: Use dynamic_cast where class hierarchy navigation is unavoidable • C.147: Use dynamic_cast to a reference type when failure to find the required class is considered an error • C.152: Never assign a pointer to an array of derived class objects to a pointer to its base Zubkov - Guidelines - C++ Russia 2017 43 • Если в классе есть виртуальная функция, деструктор должет быть виртуальными и доступным или невиртуальным и защищенным • (удаление полиморфного класса с невиртуальным деструктором через базовый указатель – неопределенное поведение) • struct B { virtual int f() = 0; // деструктор по умолчанию доступный и невиртуальный }; struct D : B { string s {"default"}; }; void use() { std::unique_ptr<B> p = std::make_unique<D>(); } // Undefined Behavior (как минимум утечка памяти из-за строки)
  • 44. Наследование (фрагмент) • C.121: If a base class is used as an interface, make it a pure abstract class • C.126: An abstract class typically doesn't need a constructor • C.127: A class with a virtual function should have a virtual or protected destructor • C.128: Virtual functions should specify exactly one of virtual, override, or final • C.131: Avoid trivial getters and setters • C.132: Don't make a function virtual without reason • C.133: Avoid protected data • C.138: Create an overload set for a derived class and its bases with using • C.140: Do not provide different default arguments for a virtual function and an overrider • C.146: Use dynamic_cast where class hierarchy navigation is unavoidable • C.147: Use dynamic_cast to a reference type when failure to find the required class is considered an error • C.152: Never assign a pointer to an array of derived class objects to a pointer to its base Zubkov - Guidelines - C++ Russia 2017 44 • Тривиальные геттеры и сеттеры не нужны • // Плохо: • class Point { int x; public: int get_x() const { return x; } void set_x(int xx) { x = xx; } }; • // Лучше • struct Point { int x = 0; }
  • 45. Шаблоны (фрагмент) • T.5: Combine generic and OO techniques to amplify their strengths, not their costs • T.61+T.62: Don’t over-parametrize • T.64: Use specialization to provide alternative implementations of class templates • T.65: Use tag dispatch to provide alternative implementations of functions • T.67: Use specialization to provide alternative implementations for irregular types • T.69: Inside a template, don't make an unqualified nonmember function call unless you intend it to be a customization point • #749 avoid recursion in variadic templates • T.122: Use templates (usually template aliases) to compute types at compile time • T.123: Use constexpr functions to compute values at compile time • T.144: Don't specialize function templates Zubkov - Guidelines - C++ Russia 2017 45
  • 46. Шаблоны (фрагмент) • T.5: Combine generic and OO techniques to amplify their strengths, not their costs • T.61+T.62: Don’t over-parametrize • T.64: Use specialization to provide alternative implementations of class templates • T.65: Use tag dispatch to provide alternative implementations of functions • T.67: Use specialization to provide alternative implementations for irregular types • T.69: Inside a template, don't make an unqualified nonmember function call unless you intend it to be a customization point • #749 avoid recursion in variadic templates • T.122: Use templates (usually template aliases) to compute types at compile time • T.123: Use constexpr functions to compute values at compile time • T.144: Don't specialize function templates Zubkov - Guidelines - C++ Russia 2017 46 • Излишняя параметризация – источник раздувания кода (даже если компилятор поддерживает ICF). • Если член шаблона зависит только от N параметров, он должен быть в базовом классе, зависящем только от этих N параметров. • // Плохо: • template<typename T> class Foo { enum { v1, v2 }; … }; • // Лучше: • struct Foo_base { enum { v1, v2 }; … }; template<typename T> class Foo : public Foo_base { … };
  • 47. Шаблоны (фрагмент) • T.5: Combine generic and OO techniques to amplify their strengths, not their costs • T.61+T.62: Don’t over-parametrize • T.64: Use specialization to provide alternative implementations of class templates • T.65: Use tag dispatch to provide alternative implementations of functions • T.67: Use specialization to provide alternative implementations for irregular types • T.69: Inside a template, don't make an unqualified nonmember function call unless you intend it to be a customization point • #749 avoid recursion in variadic templates • T.122: Use templates (usually template aliases) to compute types at compile time • T.123: Use constexpr functions to compute values at compile time • T.144: Don't specialize function templates Zubkov - Guidelines - C++ Russia 2017 47 • Рекурсия в шаблонном коде тормозит компиляцию. Ее можно избежать при помощи fold expressions, constexpr функций, std::index_sequence (std::invoke и т п) и просто pack expansions. • // Плохо: • template<class T> void pbv(vector<T>& v) {} template<class T, class H, class... Ts> void pbv(vector<T>& v, H&& h, Ts&&... Ts) { v.push_back(h); pbv(v, ts...); } • // Лучше template<class T, class... Ts) void pbv(vector<T>& v, Ts&&... Ts) { (v.push_back(ts), ...); }
  • 48. Профили • Профиль – набор правил ставящих целью обеспечить конкретную гарантию. • Type safety (типобезопасность) • Bounds safety (безопасность работы с массивами) • Lifetime safety (гарантии времени жизни объектов) • В будущем – arithmetic, concurrency, noexcept, noalloc, etc. Zubkov - Guidelines - C++ Russia 2017 48
  • 49. Профиль типобезопасности • P.4: Ideally, a program should be statically type safe • C.183: Don't use a union for type punning • Type.1: Don't use reinterpret_cast • Type.2: Don't use static_cast downcasts. Use dynamic_cast instead • Type.3: Don't use const_cast to cast away const (i.e., at all) • Type.4: Don't use C-style (T)expression casts that would perform a static_cast downcast, const_cast, or reinterpret_cast • Type.5: Don't use a variable before it has been initialized • Type.6: Always initialize a member variable Zubkov - Guidelines - C++ Russia 2017 49
  • 50. Массивы и Указатели (Bounds Profile) • ES.55: Avoid the need for range checking • Bounds.1: Don't use pointer arithmetic. Use span instead. • Bounds.2: Only index into arrays using constant expressions. • Bounds.3: No array-to-pointer decay. • Bounds.4: Don't use standard library functions and types that are not bounds-checked. Zubkov - Guidelines - C++ Russia 2017 50
  • 51. Контроль времени жизни объектов (Lifetime Profile) 1. У каждого объекта есть только один владелец 2. На объект могут ссылаться много ссылок/указателей 3. Никакая ссылка/указатель не может пережить владельца • Правила для обычной функции: • Не показывать ссылку/указатель на локальную переменную тому кто вызвал • Ссылка/указатель переданная как аргумент может быть возвращена • Указатель от new может быть возвращен если мы сообщим что этот указатель – владелец int* f(int* p) { int x = 4; return &x; // Ошибка return new int{7}; // OK, только надо отметить что это - владелец return p; // OK: откуда пришло, туда и вернется } Zubkov - Guidelines - C++ Russia 2017 51
  • 52. Контроль времени жизни объектов (Lifetime Profile) • Как отмечать владельцев? • Предпочтительно: std::unique_ptr, std::vector, std::map, std::shared_ptr, • На низком уровне (например внутри std::vector<T>): gsl::owner<T> template<class T> using owner = T; • Этот низкоуровневый owner существует только на уровне системы типов и статического анализа, в компилированном коде он неотличим от T vector<int*> f(int* p) { owner<int*> q = new int{7}; vector<int*> res = {p, q}; // OK: копия q – не владелец return res; // Ошибка: владелец должен быть возвращен или удален } Zubkov - Guidelines - C++ Russia 2017 52
  • 53. Правила будущего • T.10/I.9: Specify concepts for all template arguments • T.11: Whenever possible use standard concepts • T.12: Prefer concept names over auto for local variables • T.13: Prefer the shorthand notation for simple, single-type argument concepts • T.20: Avoid "concepts" without meaningful semantics • T.21: Require a complete set of operations for a concept • T.22: Specify axioms for concepts • T.23: Differentiate a refined concept from its more general case by adding new use patterns • T.24: Use tag classes or traits to differentiate concepts that differ only in semantics • T.25: Avoid complementary constraints • T.26: Prefer to define concepts in terms of use-patterns rather than simple syntax • T.30+31: Use !C<T> / C1<T> || C2<T> sparingly • I.6+8: Prefer Expects() for expressing preconditions/ Ensures() for expressing postconditions Zubkov - Guidelines - C++ Russia 2017 53 См также http://stroustrup.com/good_concepts.pdf
  • 54. Не-правила и мифы • NR.1: Don't: All declarations should be at the top of a function • NR.2: Don't: Have only a single return-statement in a function • NR.3: Don't: Don't use exceptions • NR.4: Don't: Place each class declaration in its own source file • NR.5: Don't: Don't do substantive work in a constructor; instead use two-phase initialization • NR.6: Don't: Place all cleanup actions at the end of a function and goto exit • NR.7: Don't: Make all data members protected Zubkov - Guidelines - C++ Russia 2017 54
  • 55. Слишком много правил? • Эти правила для всех: • Новичков, экспертов, библиотек, системщиков, обычных и необычных приложений • Никто не предлагает выучить все эти правила! • Никто не предлагает даже прочитать все эти правила! • Подавляющее большинство правил предназначено для анализаторов: • Анализ отметит возможное нарушение и покажет какое правило прочитать: • Zubkov - Guidelines - C++ Russia 2017 55
  • 56. Мы хотим хороший современный С++ • “Мы” значит “вы” • это не под силу одному человеку или одной компании • Каким вы хотите видеть код через 5 лет? • “Таким же как и сегодня” – не ответ • Модернизировать много кода – нелегко • Если ясна цель – можно к ней двигаться • Не все согласны с тем как выглядит хороший С++ • Код не должен выглядеть одинакого • Но должно быть общее ядро • Нужно обсуждать и применять правила и анализаторы • Помогайте! • Нужны правила, анализ, комментарии, редакторы https://github.com/isocpp/CppCoreGuidelines Zubkov - Guidelines - C++ Russia 2017 56
  • 57. Zubkov - Guidelines - C++ Russia 2017 57
  • 58. extras Zubkov - Guidelines - C++ Russia 2017 58
  • 59. Обработка ошибок (фрагмент) • E.1: Develop an error-handling strategy early in a design • E.2: Throw an exception to signal that a function can't perform its assigned task • E.3: Use exceptions for error handling only • E.5: Let a constructor establish an invariant, and throw if it cannot • E.12: Use noexcept when exiting a function because of a throw is impossible or unacceptable • E.13: Never throw while being the direct owner of an object • E.14: Use purpose-designed user-defined types as exceptions (not built-in types) • E.15: Catch exceptions from a hierarchy by reference • E.16: Destructors, deallocation, and swap must never fail • E.17: Don't try to catch every exception in every function • E.18: Minimize the use of explicit try/catch • E.19: Use a final_action object to express cleanup if no suitable resource handle is available Zubkov - Guidelines - C++ Russia 2017 59
  • 60. Многозадачность (избранное) • CP.4: Think in terms of tasks, rather than threads • CP.8: Don't try to use volatile for synchronization • CP.20+21: Use RAII, never plain lock()/unlock() / Use std::lock() to acquire multiple mutexes • CP.22: Never call unknown code while holding a lock (e.g., a callback) • CP.23+24: Think of a joining thread as a scoped container / a detached thread as a global container • CP.25+26: Prefer gsl::raii_thread / gsl::detached_thread • CP.31: Pass small amounts of data between threads by value, rather than by reference or pointer • CP.32: To share ownership between unrelated threads use shared_ptr • CP.42: Don't wait without a condition • CP.50: Define a mutex together with the data it protects • Use algorithms that are designed for parallelism, not algorithms with unnecessary dependency on linear evaluation • CP.60: Use a future to return a value from a concurrent task • CP.100: Don't use lock-free programming unless you absolutely have to Zubkov - Guidelines - C++ Russia 2017 60
  • 61. Управление ресурсами • R.1: Manage resources automatically using resource handles and RAII • R.3: A raw pointer (a T*) is non-owning • R.4: A raw reference (a T&) is non-owning • R.5: Prefer scoped objects • R.10+11: Avoid malloc() and free() / Avoid calling new and delete explicitly • R.12: Immediately give the result of an explicit resource allocation to a manager object • R.13: Perform at most one explicit resource allocation in a single expression statement • R.15: Always overload matched allocation/deallocation pairs • R.20: Use unique_ptr or shared_ptr to represent ownership • R.21: Prefer unique_ptr over shared_ptr unless you need to share ownership • R.22+23: Use make_shared() to make shared_ptrs / make_unique() to make unique_ptrs • R.30: Take smart pointers as parameters only to explicitly express lifetime semantics Zubkov - Guidelines - C++ Russia 2017 61
  • 62. Выражения и инструкции (избранное) • ES.5: Keep scopes small • ES.11: Use auto to avoid redundant repetition of type names • ES.20: Always initialize an object • ES.21+22: Don't introduce a variable (or constant) before you need to use it / until you have a value to initialize it with • ES.23: Prefer the {}-initializer syntax • ES.24: Use a unique_ptr<T> to hold pointers in code that may throw • ES.26: Don't use a variable for two unrelated purposes • ES.28: Use lambdas for complex initialization, especially of const variables • ES.30+31: Don't use macros for program text manipulation / for constants or "functions" • ES.45: Avoid narrowing conversions • ES.48: Avoid casts • ES.56: Avoid std::move() in application code • ES.63: Don't slice Zubkov - Guidelines - C++ Russia 2017 62
  • 63. const • P.10: Prefer immutable data to mutable data • ES.25: Declare an object const or constexpr unless you want to modify its value later on • ES.50: Don't cast away const • F.4: If a function may have to be evaluated at compile time, declare it constexpr • R.6: Avoid non-const global variables • Con.1: By default, make objects immutable • Con.2: By default, make member functions const • Con.3: By default, pass pointers and references to consts • Con.4: Use const to define objects with values that do not change after construction • Con.5: Use constexpr for values that can be computed at compile time Zubkov - Guidelines - C++ Russia 2017 63

Notes de l'éditeur

  1. Бьярне приехал бы сам, но завтра он летит на заседание комитета
  2. Если кто не знает что это такое – вы мало сидите в Интернете! главная тема CppConа в сентябре 2015го года
  3. В этой формулировке ответ тривиален:11, 14, 17 + libfun, fs, par, tm, concepts + ranges v3, hana, metaparse
  4. * справедливости ради стоит заметить укромных уголков стало больше, несмотря на то что сам язык стал проще * любимый анекдот Страуструпа
  5. изменения в стандарт –результат за 3 года при удачном стечении обстоятельств практика не на стороне языков которые пытаются заменить с++ если провести черту и сказать вот – новое а вот старое – будет как с Питоном
  6. “не делайте это” – те кому это необходимо скажут что правила не для них
  7. Не запрещать – задавать направление
  8. Гайдлайны – не о том где ставить скобочки – мы замахнулись на намного более серьезные темы висячие ссылки – помните что Раст встревожился? Это только начало
  9. – если нужен учебник, вы знаете где его взять – это правила будущего – не были отполированы до блеска перед тем как мы их выложили на гитхаб – целые секции были в зачаточном состоянии
  10. нетипичные ситуации: если нет динамической памяти или жесткое реальное время или фреймворк
  11. - Возможности, использовние которые сопряжено с риском можно поместить в библиотеку за безопасным удобным интерфейсом - Чтобы действительно достичь безопасности, у правил должны быть зубы
  12. Микрософт впереди но я надеюсь чо гуглу будет стыдно и он догонит и перегонит
  13. Квадратные скобки – это арифметика на указателе
  14. - вернувшись из профессуры в программирование бьярне увидел своими глазами как программисты воспринимают современный с++ - Вклад из финансов, програмного обеспечения, и науки
  15. Для простых задач код должен быь простым
  16. Хотя цель правил - статический анализ, некоторые правила не поддаются анализу.
  17. Пример - библиотека Ховарда Хиннанта для календарного времени
  18. Прятать в библиотеку = ту самую myCompanySL
  19. Индекс, квадратные скобки, явный размер – все это средства достижения цели
  20. Полное стирание информации о типе – это самое ужасное нарушение типобезопасность какое только можно придумать
  21. Есть такая тенденция, особенно среди сишников “давай скорее дописывай код чтобы начать его отлаживать” Многие проводят всю жизнь в отладчике Это – не программирование. Ошибка компиляции – это счастье
  22. Сюда входят аспекты дизайна для тестирования Компромисс по контрактам был достигнут, но слишком поздно
  23. функции не знают что указатель не может быть нулевым если эта информация не была передана как часть типа В финансовом мире такие классы очень популярны
  24. Выделение ресурса это инициализация пользоваться ими нельзя – кроме как во внутренних деталях RAII класса
  25. Дональд Кнут конечно гений, но… Хороший дизайн можно улучшить в будущем - рост проекта - производительность
  26. корректность проверяемая на этапе компиляции возможность оптимизации безопасная многозадачность Возврат из функций – особенность с++11
  27. - прячем указатели в умных указателях, прячем мутексы в локах Эти 11 припципов не проверяемые – это направления
  28. Фрагмент потому что правил много
  29. Кто то вызовет это не с тем размером и запустится код который хитрый хакер прописал куда надо
  30. Конструкторы, оператор + для строк Кто проверяет результат printf?
  31. Аргумент против – на аргументы по умолчанию есть ограничения (на это тоже есть гайдлайн)
  32. Если функция возвращает объект – она должна возвращать объект а не ссылку или указатель Если функция изменяет объект – он передается по ссылка а не как указатель
  33. Многие вводят дополнительные значения для классов заданных struct и class
  34. Для примера здесь приведена дата – тип у которого нет естественного пустого состояния – мы выбирает одно из возможных состояний как стандартное
  35. Допустим есть объект кирпич и у него есть поле вес. Или банковский счет (реальный счет конечно не хранит баланс как поле класса)
  36. ICF требует gold linker, COMDAT folding включен по умолчанию +SCARY итераторы как пример
  37. И с каждой новой ревизией языка возможностей избежать рекурсию становится больше
  38. Если рассказывать о каждом правиле в отдельности, мы тут просидим целый день Пользователи могут включать и выключать отдельные правила но некоторые правила в совокупности – большее чем сумма частей
  39. Все это и некоторые другие правила в совокупности гарантируют что к одному типу нельзя обратиться как к другому
  40. (range check) Либо на этапе компиляции либо интервальй цикл
  41. Помните что волнуется Раст?
  42. Концепции – это предикаты над типами, долгожданные интерфейсы для шаблонов Смысл концепции должен быть больше чем простой совокупностью ограничений
  43. популярные и ошибочные мифы
  44. Наш подход атака с трех сторон – правила + библиотека + анализ. Два без третьего не работают
  45. Мы – не Страуструп и ко, “мы” – программисты если мы понимаем в каком направлении двигаться, мы можем начать движение прямо сейчас У разных индустрий и разных ситуаций есть разные требования, но общее ядро И поэтому мы обращаемся к вам за помощью – поэтому эти правила и были выложены в сыром виде – мы хотим услышать от программистов изо всех ситуаций, во всём мире.
  46. Если будет вопрос про исключения
  47. Если будет вопрос про многозадачность