с C++11 можно помечать функции, переменные, а также аргументы функций атрибутами это влияет на компилятор
-
[[no_unique_address]]- можно этому объекту не заводить отдельный адрес (С++20) (но если 2 одинаковых типа объявить с этим атрибутом, то у них все же будут разные адреса) -
[[nodiscard]]- ставится перед функциями и говорит компилятору, что нужно выдать варнинг, если результат этой функции дискардится, то есть с её значением ничего не делается (С++17). есть функции, которые важно помечать nodiscard - те функции, результат которых стоит обязательно где-то сохранить, иначе что-то пойдет не так. например operator new, метод allocate у аллокаторов. а ещё проверка контейнера на пустоту - он помечен nodiscard, чтобы не было заблуждения, что эта функция очищает контейнер, ещё std::launder -
[[depricated("reason")]]- при написании api можно пометить функцию depricated, чтоб кидало варнинг пользователю, если он попытается ей воспользоваться (С++14) -
[[maybe_unused]]- иногда ставится перед аргументами функции, перед функциями и структурами. он говорит, что этот аргумент может не использоваться в теле функции и компилятор не должен жаловаться. зачем это ввели, если можно просто не давать имя аргумента? для шаблонного кода. может быть compile time условие, при котором этот аргумент будет использоваться. типо при каких-то T будет used argument, а при каких-то unused argument (C++17) -
[[likely]]/[[unlikely]]- можно ставить после ифа, подсказывая компилятору, что эта ветка ифа более вероятная, чем альтернативная. помогает лучше делать branch prediction в процессоре, генерировать более эффективный ассемблерный код -
[[assume]]- помогает компилятору лучше оптимировать код. например в функцию подается инт, но мы знаем, что он будет <100. тогда пишем[[assume(x<100)]];и компилятор лучше оптимизировать (C++23)