1. Нашёл вот такой proposal, где указано множество конструкций из C/C++, которые работают по-разному (и соответственно предлагается это пофиксить). Из интересного тут много кейсов с оператором запятая, скобками и тернарником (везде замешаны lvalue и другие категории значений). Ещё прикольно, что в C тип можно объявлять где хочется:
void func(struct S { int x; } s); В С++ в отличие от C можно делать так:
void bar(void);
void foo(void) {
return bar(); // OK
}
Выглядит странно, но по факту это можно юзать как замену вызову функции и
return в две строки. Ещё символьные литералы в C это
int, а не char (т.е. sizeof(‘a’) == sizeof(int)). Вот такое тоже в плюсах не скомпилится:
char buf[] = u8"text";потому что u8 это
const char8_t, когда в C это char. И пустую структуру/enum в C создать нельзя.
Короче тут гора всего интересного. Предлагаю изучить самим (дока правда огромная, но вы справитесь : ) ).
2. Давайте посмотрим на две сигнатуры функций:
template <int I> void f(A<I>, A<I+10>);
template <int I> void f(A<I>, A<I+1+2+3+4>);При выборе перегрузки компилятор споткнётся, т.к. после инстанцирования они эквивалентны. Однако с точки зрения грамматики это разные сигнатуры, потому заранее такое задетектить не получится. Такой код ill-formed, no diagnostic required (ifndr), т.е. компиляторы вольны обрабатывать такой код любым удобным образом. Можно сказать, что это некоторого рода уб.
3. Узнал об aliasing constructor у
std::shared_ptr. Какие-то дикие вещи совсем. Почитать можно вот тут. 4. Интересно, что в go использование указателей вместо значений несёт в себе гораздо бОльшие неприятности, чем в C++. Всё из-за сборщика мусора и escape analysis. Об этом можно почитать вот в такой интересной статье. Там же можно узнать, как эффективнее работать со слайсами и скрывать указатели от escape анализа.
5. Ещё вот нашлась статья под названием “Как мы себя обманываем, только бы продолжать пользоваться Golang”. Не скажу, что она убедительна, но что-то есть.
6. Небольшой тестик, чтобы выяснить, кто вы из C++.