C++ 1MIT весна 1 2020 — различия между версиями

Материал из CSC Wiki
Перейти к:навигация, поиск
(Практика 4: Гулецкий)
(Экзамен)
(не показано 46 промежуточных версий 5 участников)
Строка 1: Строка 1:
 
[[C++ 1MIT осень 1 2019|Осенний семестр]]
 
[[C++ 1MIT осень 1 2019|Осенний семестр]]
 +
 +
== Экзамен ==
 +
 +
[[C++ 1MIT весна 1 2020 — билеты|Черновик формата и финальные билеты к экзамену]] (билеты финализированы 05.06.2020 19:14 МСК)
  
 
== Лекции ==
 
== Лекции ==
Строка 16: Строка 20:
 
* [http://www.amse.ru/courses/cpp1/2010.02.10.html Ликбез по svn]
 
* [http://www.amse.ru/courses/cpp1/2010.02.10.html Ликбез по svn]
 
* Про зарезервированные имена в Си и C++: [https://stackoverflow.com/a/228797/767632 stackoverflow.com/a/228797/767632]
 
* Про зарезервированные имена в Си и C++: [https://stackoverflow.com/a/228797/767632 stackoverflow.com/a/228797/767632]
 +
* Про создание своих манипуляторов с параметрами: [https://accu.org/index.php/journals/1769 accu.org/index.php/journals/1769]
 
* [https://www.lektorium.tv/speaker/2936 ''Морально устаревшая'' версия курса в формате видео лекций.]
 
* [https://www.lektorium.tv/speaker/2936 ''Морально устаревшая'' версия курса в формате видео лекций.]
 
* ''Студенческие'' конспекты этого и ''идеологически близких'' курсов: [http://www.amse.ru/courses/cpp1/ cpp1] [http://www.amse.ru/courses/cpp1/ cpp2] [https://wiki.compscicenter.ru/index.php/%D0%A4%D0%B0%D0%B9%D0%BB:Cpp.pdf cpp3]
 
* ''Студенческие'' конспекты этого и ''идеологически близких'' курсов: [http://www.amse.ru/courses/cpp1/ cpp1] [http://www.amse.ru/courses/cpp1/ cpp2] [https://wiki.compscicenter.ru/index.php/%D0%A4%D0%B0%D0%B9%D0%BB:Cpp.pdf cpp3]
 +
 +
Про конкретные элементы C++:
 +
* [https://habr.com/ru/post/495444/ Серия статей про детали базовых элементов C++ на русском] (перегрузки, массивы, операторы...)
 +
* [https://habr.com/ru/company/jugru/blog/467299/ Концепты в C++20]
 +
* [http://jguegant.github.io/blogs/tech/sfinae-introduction.html SFINAE и member detection]
 +
* [https://www.boost.org/doc/libs/1_71_0/libs/hana/doc/html/index.html Библиотека Boost.Hana для метапрограммирования]
 +
* [https://www.youtube.com/watch?v=wQxj20X-tIU Scott Meyers "Type Deduction and Why You Care"] (видеодоклад)
 +
* [https://godbolt.org/z/hH9H27 Получение доступа к приватным типам через друзей и шаблоны] (пример кода)
 +
* [https://www.youtube.com/watch?v=St0MNEU5b0o Klaus Iglberger "Back to Basics: Move Semantics (part 1 of 2)"]
 +
* [https://www.youtube.com/watch?v=pIzaZbKUw2s Klaus Iglberger "Back to Basics: Move Semantics (part 1 of 2)"] (forwarding references)
 +
 +
Читать для общего развития:
 +
* [https://isocpp.org/wiki/faq ISO C++ Wiki]
 +
* [http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines C++ Core Guidelines]
 +
* [http://www.gotw.ca/gotw/ GotW] (Guru of the Week by Herb Sutter)
 +
* [https://abseil.io/tips/ TotW] (Tips of the Week by Google)
 +
* Что угодно от Scott Meyers
 +
* Что угодно от Andrei Alexandrescu
 +
 +
Extra:
 +
* [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1705r0.html P1705R0 Enumerating Core Undefined Behavior] — попытка перечислить хоть какие-то UB.
 +
* [https://2019.cppconf-piter.ru/2019/spb/talks/3iz1z0htlsvkb8a4kyitgd/ Доклад "Сериализация объектов с блэкджеком и метапрограммированием"]
 +
* [https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms More C++ Idioms Wikibook]
  
 
Книги:
 
Книги:
Строка 28: Строка 56:
 
** Г. Сеттер, Решение сложных задач на C++/Новые сложные задачи на C++
 
** Г. Сеттер, Решение сложных задач на C++/Новые сложные задачи на C++
 
** Р. Седжвик, Алгоритмы на C++
 
** Р. Седжвик, Алгоритмы на C++
 +
 +
=== Софт ===
 +
Установка clang 10 и libc++ в Ubuntu:
 +
 +
# Добавляем в конец <code>/etc/apt/sources.list</code> две строчки, соответствующие вашей версии Ubuntu (смотри <code>/etc/lsb-release</code>). Например, для Ubuntu 16.04.1 LTS:
 +
deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main
 +
deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main
 +
# <code>sudo apt update</code>
 +
# <code>sudo apt install clang-10 libc++-10-dev libc++abi-10-dev libc++1-10 libc++abi1-10</code> или по регулярке: <code>sudo apt install clang-10 'libc\+\+.*10.*'</code>
 +
 +
Можно установить на Ubuntu 18.04 после [http://robs-got-a-blog.blogspot.com/2019/10/installing-clang-9-on-ubuntu-1804-lts.html этих] шагов.
 +
 +
Потом можно компилировать при помощи команды <code>clang++-10 -stdlib=libc++ main.cpp -o main</code>. Почти все флаги как у GCC, включая warnings.
 +
 +
Если вы меняете компилятор — обязательно сделайте <code>make clean</code> и удалите все промежуточные файлы. Объектные файлы между разными компиляторами (и даже между одним компилятором с разными ключами) несовместимы и в лучшем случае не слинкуются, в худшем будет UB/IFNDR.
  
 
=== Осенний семестр ===
 
=== Осенний семестр ===
Строка 51: Строка 94:
  
 
== Оценка за курс ==
 
== Оценка за курс ==
 +
Правила оценки за C++ за 3-4 модуль совпадают с [[C++ 1MIT осень 1 2019#Оценка за курс|осенним семестром]],
 +
однако сейчас формальная оценка выставляется [[Оценки 1MIT весна 1 2020#Предметы|вместе с UNIX и хвостом ОП]].
 +
 +
Можно смотреть текущую оценку по C++ в таблице в столбцах "Оптимистично" (в предположении, что экзамен сдан идеально и непроверенные работы получат примерно такие же оценки, как сейчас), "Без блоков" и "C++".
 +
 
== Лабораторные и домашние ==
 
== Лабораторные и домашние ==
  
Строка 129: Строка 177:
 
* https://godbolt.org/z/qyWCQl
 
* https://godbolt.org/z/qyWCQl
  
 +
23.01.20
 +
* https://github.com/google/googletest
 +
* https://habr.com/ru/post/119090/
 +
 +
 +
* http://www.gnu.org/software/ncurses/ncurses.html
 +
* https://invisible-island.net/ncurses/
 +
* https://invisible-island.net/ncurses/man/ncurses.3x.html
 +
* http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
 +
* https://code-live.ru/post/cpp-ncurses-hello-world/
 +
* https://www.linuxjournal.com/content/getting-started-ncurses
 +
* https://www.nixp.ru/articles/102.html
 +
 +
 +
* https://github.com/google/benchmark
 +
* https://habr.com/ru/company/wunderfund/blog/325634/
 +
 +
* https://stackoverflow.com/questions/4384765/whats-the-difference-between-pretty-function-function-func
 +
 +
30.01.20
 +
* https://gitlab.com/snippets/1934679
 +
* https://stackoverflow.com/questions/15575272/how-to-use-clone-in-c-with-multiple-inheritance-of-abstract-classes
 +
 +
06.02.20
 +
* https://en.cppreference.com/w/cpp/memory/new/nothrow
 +
* https://medium.com/cpp-station/exception-handling-in-constructors-26bf4c811b46
 +
* https://en.cppreference.com/w/cpp/error/logic_error
 +
* https://isocpp.org/wiki/faq/exceptions#throwing-polymorphically
 +
* https://stackoverflow.com/a/77336
 +
* http://boostorg.github.io/stacktrace/index.html
 +
* http://man7.org/linux/man-pages/man3/backtrace.3.html
 +
* https://habr.com/ru/post/279111/
 +
* https://monoinfinito.wordpress.com/series/exception-handling-in-c/
 +
* https://wildwolf.name/how-to-get-the-source-of-an-uncaught-exception-in-cpp/
 +
* https://en.wikipedia.org/wiki/Exception_safety
 +
* https://github.com/bombela/backward-cpp
 +
 +
20.02.20
 +
* https://gitlab.com/snippets/1943032
 +
 +
27.02.20
 +
* https://gitlab.com/snippets/1945364
 +
 +
05.03.20
 +
* https://gitlab.com/snippets/1947486
 +
 +
12.03.20
 +
* https://gitlab.com/snippets/1952188
  
 
==== Требования корректности, предъявляемые к работам ====
 
==== Требования корректности, предъявляемые к работам ====
Строка 162: Строка 258:
 
Если строчку кода можно удалить без изменения поведения программы, значит, ее нужно удалить.
 
Если строчку кода можно удалить без изменения поведения программы, значит, ее нужно удалить.
  
'''4. В языке Си использовать <code>void(void)</code>, а не <code>void()</code>.'''
+
'''4. Отсутствие утечек памяти, Undefined Behaviour и других проблем'''
 
 
'''5. Отсутствие утечек памяти, Undefined Behaviour и других проблем'''
 
 
Ваша программа должна компилироваться и корректно завершаться, а соответствующая утилита не должна находить какие-либо проблемы:
 
Ваша программа должна компилироваться и корректно завершаться, а соответствующая утилита не должна находить какие-либо проблемы:
 
* в debug и release (-DNDEBUG) режимах сборки
 
* в debug и release (-DNDEBUG) режимах сборки
Строка 175: Строка 269:
 
включая комбинации этих опций, кроме случаев ошибок в самих утилитах и несоответствия компилятора Стандарту. (Да, и то, и то бывает.)
 
включая комбинации этих опций, кроме случаев ошибок в самих утилитах и несоответствия компилятора Стандарту. (Да, и то, и то бывает.)
  
'''6. Именование должно быть понятным кому угодно, не только лишь Автору, но и всем.'''
+
'''5. Именование должно быть понятным кому угодно, не только лишь Автору, но и всем.'''
 
Имя функции должно отражать особенности ее поведения.
 
Имя функции должно отражать особенности ее поведения.
 
Имя переменной должно быть говорящим.
 
Имя переменной должно быть говорящим.
Строка 182: Строка 276:
 
Этот раздел не может быть формализовать и ложится целиком и полностью на здравый смысл. Здесь зачастую нет "идеального" решения, и если вам не удается достичь совершенства - не расстраивайтесь, таких как вы - легион. Проблема именования является одной из ключевых в программировании, вызывает большое количество дискуссий, требует много времени и внимания разработчиков.
 
Этот раздел не может быть формализовать и ложится целиком и полностью на здравый смысл. Здесь зачастую нет "идеального" решения, и если вам не удается достичь совершенства - не расстраивайтесь, таких как вы - легион. Проблема именования является одной из ключевых в программировании, вызывает большое количество дискуссий, требует много времени и внимания разработчиков.
  
'''7. Если была допущена какая-то проблема в реализации функции, должен быть написан тест, детектирующий эту проблему.'''
+
'''6. Если была допущена какая-то проблема в реализации функции, должен быть написан тест, детектирующий эту проблему.'''
  
'''8. Использование сторонних функций только из стандартной библиотеки языка, если противное явно не оговорено в задании.'''
+
'''7. Использование сторонних функций только из стандартной библиотеки языка, если противное явно не оговорено в задании.'''
  
 
В частности, написание C++ кода без привязки к платформе Linux; отсутствие POSIX-специфичных функций и структур. Не смотря на то, что целевая платформа - Linux, привычка писать платформенно-специфичный или компиляторо-специфичный код может однажды сыграть злую шутку. Комитет по стандартизации стремится к тому, чтобы не было необходимости писать такой код, включая новые и новые платформенно-независимые вещи в стандарт языка. Если "совсем никак", то лучше обернуть специфичную функцию: сделать <code>size_t mygetline(char **lineptr, size_t *n, FILE *stream) {return getline(lineptr, n, stream);}</code>  
 
В частности, написание C++ кода без привязки к платформе Linux; отсутствие POSIX-специфичных функций и структур. Не смотря на то, что целевая платформа - Linux, привычка писать платформенно-специфичный или компиляторо-специфичный код может однажды сыграть злую шутку. Комитет по стандартизации стремится к тому, чтобы не было необходимости писать такой код, включая новые и новые платформенно-независимые вещи в стандарт языка. Если "совсем никак", то лучше обернуть специфичную функцию: сделать <code>size_t mygetline(char **lineptr, size_t *n, FILE *stream) {return getline(lineptr, n, stream);}</code>  
  
'''9. Не использовать exit где-либо, кроме main.cpp'''
+
'''8. Не использовать exit где-либо, кроме main.cpp'''
 
Представьте, что вы пользуетесь какой-то библиотекой. Позвали функцию из нее, а ей что-то не понравилось (не хватило памяти, запись на диск не удалась, ...) и она позвала в своих недрах exit. Это полная катастрофа, потому что на этом работа программы завершается, а в месте вызова вы об этом даже не узнаете. Это может быть очень болезненно: может быть, в оперативной памяти хранится результат длительных вычислений, или ценная информация, это могли быть данные, за которые нужно платить (обращения к платным сервисам) и много что еще. Главное - за вас кто-то другой решил, как программа должна себя вести. Никогда не используйте exit в библиотеках.
 
Представьте, что вы пользуетесь какой-то библиотекой. Позвали функцию из нее, а ей что-то не понравилось (не хватило памяти, запись на диск не удалась, ...) и она позвала в своих недрах exit. Это полная катастрофа, потому что на этом работа программы завершается, а в месте вызова вы об этом даже не узнаете. Это может быть очень болезненно: может быть, в оперативной памяти хранится результат длительных вычислений, или ценная информация, это могли быть данные, за которые нужно платить (обращения к платным сервисам) и много что еще. Главное - за вас кто-то другой решил, как программа должна себя вести. Никогда не используйте exit в библиотеках.
 
Во всех заданиях прослеживается структура: сделать некоторый набор действий в рамках некоторой модели. Модель находится в одном месте, управляющая логика - в другом. Здесь проходит условная черта: модель - это библиотека, управляющая логика - конечный пользовательский код.
 
Во всех заданиях прослеживается структура: сделать некоторый набор действий в рамках некоторой модели. Модель находится в одном месте, управляющая логика - в другом. Здесь проходит условная черта: модель - это библиотека, управляющая логика - конечный пользовательский код.
 
Обработка ошибок должна осуществляться с помощью кодов возврата либо исключений.
 
Обработка ошибок должна осуществляться с помощью кодов возврата либо исключений.
  
'''10. Пространства имен'''
+
'''9. Пространства имен'''
 
Не писать ничего в глобальное пространство имен в заголовочных файлах. И не использовать `using namespace` на неограниченный scope (например, в начале .cpp файла).  
 
Не писать ничего в глобальное пространство имен в заголовочных файлах. И не использовать `using namespace` на неограниченный scope (например, в начале .cpp файла).  
  
Строка 199: Строка 293:
  
 
== Практика 2: Свиридкин ==
 
== Практика 2: Свиридкин ==
 +
 +
Репозиторий с примерами https://github.com/Nekrolm/hse_cpp_examples
 +
 
== Практика 3: Лапшин ==
 
== Практика 3: Лапшин ==
 
== Практика 4: Гулецкий ==
 
== Практика 4: Гулецкий ==
Строка 209: Строка 306:
  
 
[https://github.com/evlinsky/cpp/tree/master/ta/huletski/HSE_S20 Код с практик]
 
[https://github.com/evlinsky/cpp/tree/master/ta/huletski/HSE_S20 Код с практик]
 +
 +
== Практика 4: Алфёров ==
 +
 +
* Почта для домашек: [mailto:vasily.v.alferov@gmail.com vasily.v.alferov@gmail.com]
 +
* Телега для телег: [https://t.me/vasiliyalferov vasiliyalferov]
 +
 +
Материалы с практик:
 +
 +
* 9 апреля: [https://gist.github.com/vasalf/aa36e02d305fc4cbfc3a066a6ecf6c64 Tag dispatching, Erase-remove idiom & Mutable lambdas]
 +
* 14 мая: [https://gist.github.com/vasalf/a2af0c17fcb01486a51f29f98fcdda3d SFINAE]
 +
 +
Как ставить Hana на несвежие убунты:
 +
 +
# Скачать релиз [https://github.com/boostorg/hana/releases отсюда].
 +
# Распаковать куда-нибудь.
 +
# Компилировать с дополнительным флагом "-I HANA_DIR/hana-boost-1.73.0/include".
 +
 +
Как ставить Hana на маки:
 +
 +
Проще всего brew install boost.

Версия 16:15, 5 июня 2020

Осенний семестр

Экзамен

Черновик формата и финальные билеты к экзамену (билеты финализированы 05.06.2020 19:14 МСК)

Лекции

Лектор: Суворов Егор Федорович (egor_suvorov@mail.ru)

Весенний семестр

Планы лекций Егора: github.com/yeputons/hse-2019-cpp

Прочие материалы

Ссылки:

Про конкретные элементы C++:

Читать для общего развития:

Extra:

Книги:

  • Язык C++
    • Б. Страуструп, Язык программирования С++
    • Б. Эккель, Философия C++
  • Дополнительно
    • Б. Страуструп, Дизайн и эволюция языка C++
    • С. Майерс, Эффективное использование С++/Эффективное использование STL
    • Г. Сеттер, Решение сложных задач на C++/Новые сложные задачи на C++
    • Р. Седжвик, Алгоритмы на C++

Софт

Установка clang 10 и libc++ в Ubuntu:

  1. Добавляем в конец /etc/apt/sources.list две строчки, соответствующие вашей версии Ubuntu (смотри /etc/lsb-release). Например, для Ubuntu 16.04.1 LTS:
deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main
deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main
  1. sudo apt update
  2. sudo apt install clang-10 libc++-10-dev libc++abi-10-dev libc++1-10 libc++abi1-10 или по регулярке: sudo apt install clang-10 'libc\+\+.*10.*'

Можно установить на Ubuntu 18.04 после этих шагов.

Потом можно компилировать при помощи команды clang++-10 -stdlib=libc++ main.cpp -o main. Почти все флаги как у GCC, включая warnings.

Если вы меняете компилятор — обязательно сделайте make clean и удалите все промежуточные файлы. Объектные файлы между разными компиляторами (и даже между одним компилятором с разными ключами) несовместимы и в лучшем случае не слинкуются, в худшем будет UB/IFNDR.

Осенний семестр

Презентации первого семестра Евгения Линского (I поток):

Планы лекций Егора (II поток): github.com/yeputons/hse-2019-cpp

Презентации ликбеза по С:

Оценка за курс

Правила оценки за C++ за 3-4 модуль совпадают с осенним семестром, однако сейчас формальная оценка выставляется вместе с UNIX и хвостом ОП.

Можно смотреть текущую оценку по C++ в таблице в столбцах "Оптимистично" (в предположении, что экзамен сдан идеально и непроверенные работы получат примерно такие же оценки, как сейчас), "Без блоков" и "C++".

Лабораторные и домашние

Практика 1: Соколов

Преподаватель: Вячеслав Соколов (vi.soksok@gmail.com, +7 921 780 11 12)

Trac: sokolov

Письма просьба идентифицировать префиксом в теме [HSE][CPP]

Linux

  • Исследование бинарных артефактов
    • nm list symbols from object files
    • readelf displays information about ELF files
    • c++filt demangle symbols
Ограничение процесса по ресурсам в Linux
  • Рекомендуется использовать systemd-run: systemd-run --scope -p MemoryLimit=2M -p MemoryAccounting=yes ./a.out. В этом примере ограничивается память 2 мебибайтами.

Дальнеший текст - для тех, кто хочет более глубокого погружения.

Краткий перечень ключевых слов и какие есть проблемы при использовании:

  • cgroups - можно просто взять и использовать, но придется повозиться, не очень удобно. Требует понимания, как что устроено, соответственно и времени потребует.
  • ulimit - много разных версий, от конкретного shell-а зависит как пример использования, так и доступная функциональность. Легко может не сработать.
  • Использование LD_PRELOAD и собственного аллокатора памяти. У меня аллокатор libmemrestrict.so по ссылке из статьи крашится с SEGFAULT, возможно, это я где-то напортачил. Если захотите идти этим путем - спрашивайте меня, есть несколько нетрививальных моментов.
  • docker - популярный способ работы с контейнерами

Для тех, кому хочется поэкспериментировать с консолью

  • Эмуляторы терминала
    • terminator
    • tilix
    • а также много других, легко ищутся
  • Shell
    • bash по умолчанию, но есть кое-что поудобнее, например
    • fish - interactive shell, создан, чтобы быть удобным
    • zsh - для любителей писать скрипты

Системы сборки

Для наших нужд достаточно Make

Если проект становится большим, нужно что-то посложнее, например (альтернативы):

Полезные сайты

  • godbolt - compiler explorer (удобно делиться примерами)
  • ideone - возможность делиться кодом, поддержка разных ЯП, исполнение кода online
  • stackoverflow - огромное количество ответов на разные вопросы. Прежде чем самому задавать вопрос, будет полезно ознакомиться с текстом https://habr.com/ru/post/339038/
  • [1] - список библиотек из 1-2 файлов
  • [2] - список open-source библиотек на языке Си++
  • [3] - история языка Си++

Статьи

Практика

16.01.20

23.01.20



30.01.20

06.02.20

20.02.20

27.02.20

05.03.20

12.03.20

Требования корректности, предъявляемые к работам

1. Проверка контрактов функций.

На мой взгляд, чуть ли не единственной обязательной к использованию парадигмой и доступной во всех языках программирования, выше ассемблера, является [4]. Ключевые понятия: предусловия, постусловия и инварианты. В языках C/C++ соблюдение контрактов контролируется с помощью assert, возведения сигналов, бросания исключений.

Данный подход является обязательным, потому что гарантирует максимально раннее обнаружение проблемы. Игнорирование подхода приводит к проблемам в самых неожиданных местах. Программа может вести себя как корректная, хотя содержит в себе большое количество ошибок, пока очередная проблема не приведет к лавине. Примеры неожиданно всплывших проблем: https://software-testing.ru/library/testing/general-testing/2082-horrible-bugs

Требуется производить проверку контрактов:

  • предусловий: с помощью assert в начале функции. Пример: Указатель: может быть нулевым? Нет? assert.
  • инвариантов: по ходу выполнения функции. Пример: по ходу алгоритма нужно произвести удаление элемента из контейнера. Можно проверить, что этот элемент вообще присутствует в контейнере.
  • постусловий: В конце функции и с помощью тестов. Пример: в результате удаления вершины из списка она не должна быть достижима из головы списка. Это можно провалидировать с помощью assert.

Проверки контрактов упрощают восприятие кода и могут при определенном стечении обстоятельств заменять документацию.

Q: но ведь проверка контракта может быть медленной, теряем производительность

A: используйте assert для медленных проверок, если нужна производительность - используется release режим сборки, туда эти проверки не попадут

2. Стиль кода совпадает во всем проекте.

Либо везде табуляции для отступов, либо везде пробелы. Именование переменных либо везде snake_case, либо везде camelCase. Желательно отделять разные сущности друг от друга написанием. Например, можно выделять:

  • МАКРОСЫ()
  • КОНСТАНТЫ
  • функцииКоторыеЧтоТоДелают()
  • переменныеКоторыеЗачемТоПонадобились
  • ИменаКлассовИСтруктур

Допустимы конфликты написания (когда по имени нельзя однозначно восстановить, какая это языковая конструкция), но не стоит для всего использовать одно и то же написание.

3. Каждая строчка кода что-то делает.

Если строчку кода можно удалить без изменения поведения программы, значит, ее нужно удалить.

4. Отсутствие утечек памяти, Undefined Behaviour и других проблем Ваша программа должна компилироваться и корректно завершаться, а соответствующая утилита не должна находить какие-либо проблемы:

  • в debug и release (-DNDEBUG) режимах сборки
  • будучи запущенной из-под gdb
  • будучи запущенной из-под valgrind
  • после компиляции с -fsanitize=address
  • после компиляции с -fsanitize=undefined
  • после компиляции с -fsanitize=leak
  • на разных версиях разных компиляторов (gcc, clang, msvc, ...)

включая комбинации этих опций, кроме случаев ошибок в самих утилитах и несоответствия компилятора Стандарту. (Да, и то, и то бывает.)

5. Именование должно быть понятным кому угодно, не только лишь Автору, но и всем. Имя функции должно отражать особенности ее поведения. Имя переменной должно быть говорящим. Лучше всего, если вне контекста можно понять, за что отвечает / что делает та или иная функция, структура, переменная. Стандарт языка в этом смысле не является примером для подражания.

Этот раздел не может быть формализовать и ложится целиком и полностью на здравый смысл. Здесь зачастую нет "идеального" решения, и если вам не удается достичь совершенства - не расстраивайтесь, таких как вы - легион. Проблема именования является одной из ключевых в программировании, вызывает большое количество дискуссий, требует много времени и внимания разработчиков.

6. Если была допущена какая-то проблема в реализации функции, должен быть написан тест, детектирующий эту проблему.

7. Использование сторонних функций только из стандартной библиотеки языка, если противное явно не оговорено в задании.

В частности, написание C++ кода без привязки к платформе Linux; отсутствие POSIX-специфичных функций и структур. Не смотря на то, что целевая платформа - Linux, привычка писать платформенно-специфичный или компиляторо-специфичный код может однажды сыграть злую шутку. Комитет по стандартизации стремится к тому, чтобы не было необходимости писать такой код, включая новые и новые платформенно-независимые вещи в стандарт языка. Если "совсем никак", то лучше обернуть специфичную функцию: сделать size_t mygetline(char **lineptr, size_t *n, FILE *stream) {return getline(lineptr, n, stream);}

8. Не использовать exit где-либо, кроме main.cpp Представьте, что вы пользуетесь какой-то библиотекой. Позвали функцию из нее, а ей что-то не понравилось (не хватило памяти, запись на диск не удалась, ...) и она позвала в своих недрах exit. Это полная катастрофа, потому что на этом работа программы завершается, а в месте вызова вы об этом даже не узнаете. Это может быть очень болезненно: может быть, в оперативной памяти хранится результат длительных вычислений, или ценная информация, это могли быть данные, за которые нужно платить (обращения к платным сервисам) и много что еще. Главное - за вас кто-то другой решил, как программа должна себя вести. Никогда не используйте exit в библиотеках. Во всех заданиях прослеживается структура: сделать некоторый набор действий в рамках некоторой модели. Модель находится в одном месте, управляющая логика - в другом. Здесь проходит условная черта: модель - это библиотека, управляющая логика - конечный пользовательский код. Обработка ошибок должна осуществляться с помощью кодов возврата либо исключений.

9. Пространства имен Не писать ничего в глобальное пространство имен в заголовочных файлах. И не использовать `using namespace` на неограниченный scope (например, в начале .cpp файла).

To be continued.

Практика 2: Свиридкин

Репозиторий с примерами https://github.com/Nekrolm/hse_cpp_examples

Практика 3: Лапшин

Практика 4: Гулецкий

Преподаватель: Артур Гулецкий (hatless.fox@gmail.com)

Префикс в теме письма: [C++TA]

Trac: huletski

Код с практик

Практика 4: Алфёров

Материалы с практик:

Как ставить Hana на несвежие убунты:

  1. Скачать релиз отсюда.
  2. Распаковать куда-нибудь.
  3. Компилировать с дополнительным флагом "-I HANA_DIR/hana-boost-1.73.0/include".

Как ставить Hana на маки:

Проще всего brew install boost.