https://telegra.ph/C-compilation-part-1-09-04
cpp
Канал посвященный моим попыткам освоить C++ и немного компиляторы. Буду сюда кидать интересные для меня вещи.
Графики
📊 Средний охват постов
📉 ERR % по дням
📋 Публикации по дням
📎 Типы контента
Лучшие публикации
18 из 18Продолжение граблей со static_cast В прошлый раз мы выяснили что при касте к братскому классу компилятор вставит вызов метода того типа которым помечен объект. Рассмотрим данный код: struct Base {}; struct ActualChild : Base { int foo() { return 1; } }; struct OtherChild : Base { int foo() { return 2; } }; int main() { ActualChild actual; OtherChild other_ptr = static_cast<OtherChild>((Base*)&actual); return other_ptr->foo(); } https://godbolt.org/z/E1z194zf6 Результатом программы будет 2 и в ок...
Битовые флаги Недавно наткнулся в одной библиотеке на интересный способ объявления и использования битовых флагов которым хочу поделиться. Но перед тем как перейти к нему хотел бы показать как я бы лично их реализовал и чем мой метод хуже. Для начала определение – под битовыми флагами я имею ввиду именованные свойства с которыми можно проводить битовые операции (побитовое И, побитовое ИЛИ и т.д). Определение наверно только запутало давайте лучше к примеру как я бы это реализовал: struct File { i...
Оптимизация с использованием данных профилятора. Часть 2 Давайте посмотрим как это может работать. Шаг 1: Компилируем программу с несколькими флагами позволяющими сопоставить собранные метрики с исходным кодом: clang++ -O2 -gline-tables-only -fdebug-info-for-profiling -funique-internal-linkage-names sample.cc -o sample Шаг 2: Исполняем собранную программу с профилятором: sudo perf record -b -e BR_INST_RETIRED.NEAR_TAKEN:uppp ./sample 1 Шаг 3: Так как perf это внешняя для llvm утилита, нам нужно ...
Продолжение. В таком случае нам на помощь приходит std::bit_cast , либо его аналог написанный вручную: #include <cstdint> #include <cstring> #include <iostream> struct Person { int age; char cityInfo[4]; }; struct City { long id; }; int main() { Person me; City city; std::memcpy(&city, &me.cityInfo, sizeof(City)); std::cout << city.id << std::endl; return 0; } И хоть в данном случае мы и выделили на стеке память под новую структуру, в реальности в большинстве случаев компилятор может оптимизиров...
https://telegra.ph/C-Kompilyaciya-Preprocessor-09-10
Еще одна проблема с переходом на низкоуровневые языки — операции с указателями (pointer). Про это знают, наверно, все программисты, но иногда случаются ситуации, в которых с первого раза и не предположить подводных камней. Рассмотрим следующий код: vector<int> v; v.push_back(1); cout << v[0] << " "; int p = &(--v.end()); (p) = 2; cout << v[0] << " "; (p) = 3; cout << v[0] << " "; Данный код выведет на экран значения: 1 2 3 Казалось бы все как мы и предполагали. Проблема данного кода в том, что в...
Грабли со static_cast Недавно наткнулся на забавную багу в коде, которая заставила задуматься над поведением, казалось бы банального, static_cast. Давайте рассмотрим следующее дерево наследования: struct Base {}; struct ActualChild : Base {}; struct OtherChild : Base {}; Давайте теперь сделаем static_cast между братскими классами: ActualChild obj; ActualChild actual_ptr = &obj; Base base_ptr = actual_ptr; OtherChild other_ptr = static_cast<OtherChild>(base_ptr); В теории static_cast не должен де...
Перегрузка операторов (часть 2) Ладно, вы еще не устали? Тогда вот вам на десерт самый абсурдный оператор. Оператор перечисления ,. Да, да, его можно перегрузить. Давайте для начала вспомним когда он может использоваться. Ну например в следующих строчках: int main() { int a = 0; int b = 0; for (a = 0, b = 0; a < 2 && b < 2; a++, b++); return a, b; } Что тут делает этот оператор? Правильно, вычисляет по цепочке все выражения и возвращает самое правое. Давайте попробуем его перегрузить: struct Cra...
https://telegra.ph/Predkompilirovannye-zagolovki-10-16