Среди улучшений в Clang 21:
- Возможности, связанные с С++:
- По аналогии с GCC реализована возможность использования константных выражений в ассемблерных вставках, определяемых директивой "asm":
Код:
int foo() {
asm((std::string_view("nop")) ::: (std::string_view("memory")));
} - Добавлены расширенные варианты выражений "new" и "delete", поддерживающие аргумент "std::type_identity‹T›", через который можно указать информацию о типе объекта, для которого выделяется или освобождается память.
- Добавлена возможность вычисления на этапе компиляции (в контексте константного выражения) лямбда-функций, захватывающих структурированные привязки (structured binding) .
- По аналогии с GCC реализована возможность использования константных выражений в ассемблерных вставках, определяемых директивой "asm":
- Возможности, связанные с будущим стандартом C++2с (C++26):
- В структурированные привязки добавлена возможность использования синтаксиса "..." для указания пакетов (pack), захватывающих оставшееся число элементов из присваиваемой последовательности.
Код:
auto [x,y,z] = f();
// в переменные x, y, z будут записаны три элемента, возвращённые f().
auto [...xs] = f();
// в пакет xs будут записаны все элементы, возвращённые f().
auto [x, ...rest] = f(); // В x будет записан первый элемент, а в rest - остальные.
auto [x, y, ...rest] = f(); // В x будет записан первый элемент, в y - второй, а в rest - третий.
auto [x, ...rest, z] = f(); // в x - первый, в rest - второй, в z - третий. - Добавлена поддержка "тривиальной перемещаемости" типов (Trivial Relocatability), позволяющей оптимизировать перемещения объектов заданного типа через их клонирование в памяти без вызова конструкторов или деструкторов. Для классов реализованы свойства memberwise_trivially_relocatable и memberwise_replaceable, а для низкоуровневого перемещения одного или нескольких объектов добавлены функции trivially_relocate_at и trivially_relocate.
- Появилась возможность применения структурированного связывания (structured binding) в качестве условия в операторах "if" и "switch".
- Реализована поддержка прикрепления функции main() к глобальному модулю и определения функции main() в именованных модулях.
- В структурированные привязки добавлена возможность использования синтаксиса "..." для указания пакетов (pack), захватывающих оставшееся число элементов из присваиваемой последовательности.
- Возможности, развиваемые для будущего стандарта C2y:
- Устранено неопределённое поведение при использовании выражений с типом void в некоторых контекстах, например, "(void)(void)1;".
- Разрешено не завершать файл с исходным кодом символом новой строки.
- Добавлены новые префиксы для восьмеричных литералов - "0o" и "0O", а также восьмеричные и шестнадцатеричные escape-последовательности "\o{...}" и "\x{...}". Поддержка восьмеричных литералов 0xxx объявлена устаревшей. Например, "0o123" и "\o{123}" вместо "0123".
- Добавлен оператор "_Countof" для определения количества элементов в массиве. Также добавлен заголовочный файл stdcountof.h, определяющий вариант макроса "countof", реализованный через "_Countof".
- Возможности, определённые в Си-стандарте C23:
- Разрешено переопределять tag‑типы (struct, union, enum) в пределах одного блока трансляции, если повторные определения структурно эквивалентны (то же число членов, одинаковые типы и имена тегов).
- Упрощено использование списков с переменным числом аргументов (variadic). Разрешено использовать
одиночный вариативный параметр в имени типа. - Добавлена совместимая с GCC встроенная функция "__builtin_c23_va_start()", улучшающая поведение диагностики для макроса va_start() в режиме C23.
- В режиме совместимости с компилятором MSVC разрешено использование спецификатора inline при объявлении типа функции через typedef, например, "typedef int inline Foo(int);"
- Разрешено использовать квалификатор "restrict" для типов массивов с элементами-указателями.
- Новые предупреждения компилятора:
- "-Wdefault-const-init-var" и "-Wdefault-const-init-field" - выявление помеченных признаком const переменных и полей, определённых без явной инициализации.
- "-Wimplicit-void-ptr-cast" - диагностика неявного преобразования из типа "void*" в другой тип указателя.
- "-Wc++-keyword" - выявление использования ключевых слов "C++" в качестве идентификаторов в "C".
- "-Wc++-hidden-decl" - выявление использования типов тегов, видимых в "C", но не видимых в "C++" из-за ограничения области видимости.
Код:
struct S {
struct T {
int x;
} t;
};
struct T t; // предупреждение, так как корректно в Си, но некорректно в C++ - "-Wimplicit-int-enum-cast" - выявление неявных преобразований в С-коде из целочисленных типов в тип перечислений, несовместимых с "C++".
- "-Wtentative-definition-compat" - диагностика повторяющихся определений в "C", несовместимых с "C++" (например, "int i;int i;").
- "-Wunterminated-string-initialization" и "-Wc++-unterminated-string-initialization" - выявление операций инициализации строковых литералов, в которых не вмещается разделитель с нулевым кодом. Для пометки полей и переменных в коде на Си, не требующих финального нулевого символа, добавлен атрибут
"nonstring".Код:
char buf1[3] = "foo"; // предупреждение
char buf2[3] = "fo\0"; // всё Ok. - "-Wjump-misses-init" - диагностика перехода через goto или switch/case, пропускающего инициализацию локальной переменной.
- "-Wundef-true" - предупреждает об использовании значения "true" в препроцессоре C без определения.
- "-Wnrvo" - диагностика пропущенных NRVO (Named Return Value Optimization).
- Новые флаги компилятора:
- "-fprofile-continuous" - включение непрерывной синхронизации профиля в файл.
- "-ftime-report-json" - вывод сведений о времени компиляции в формате JSON.
- "-ignore-pch" - отключение предкомпилированных заголовков.
- "-fthinlto-distributor" и "-Xthinlto-distributor" - для применения DTLTO (Integrated Distributed ThinLTO).
- "-static-libclosure" - для статического связывания runtime расширения Blocks на платформе Windows.
- Расширены средства диагностики и статического анализа, добавлены новые проверки (более сотни улучшений, связанных с диагностикой).
- Улучшены бэкенды для архитектур ARM, Aarch64, AMDGPU, x86, RISC-V, LoongArch, MIPS и PowerPC. В бэкенд для RISC-V добавлена экспериментальная поддержка ассемблера для расширений Qualcomm uC, Andes и SiFive.
Источник: https://www.opennet.ru/opennews/art.shtml?num=63783
(opennet.ru, основная лента)