W bazie kodu, na podstawie której formowany jest planowany na wiosnę przyszłego roku wydatek zestawu kompilatorów GCC 15, wprowadzono zmianę, która domyślnie używa standardu C23 z rozszerzeniami GNU („-std=gnu23”) podczas kompilacji programów w języku C (wcześniej domyślnie używano standardu C17 — „-std=gnu17”). Zmiana ta może potencjalnie spowodować problemy podczas budowy istniejących projektów, ponieważ w nowym standardzie występują różnice, takie jak dodanie stałej nullptr, typów _BitInt(n) oraz słów kluczowych bool, true i false, które mogą kolidować z identyfikatorami o tych samych nazwach używanymi w aplikacjach.
Standard C23 (ISO/IEC 9899:2024) został oficjalnie opublikowany przez Międzynarodową Organizację Normalizacyjną (ISO) 31 października 2024 roku. Wśród zmian w nowym standardzie:
- Usunięto możliwość definiowania funkcji w stylu K&R C, używanym przed przyjęciem specyfikacji ANSI C i opisanym w książce „The C Programming Language” autorstwa Kernighana i Ritchiego. Styl K&R zakłada opisanie typów argumentów po definicji funkcji, na przykład „int add(a, b) int a, b; {}”.
- Nieoznaczone parametry funkcji — brak obowiązku podawania nazw nieużywanych parametrów przy definiowaniu funkcji (jak w C++). Na przykład, teraz można pisać „int f(int, int) { return 7; }”.
- Wsparcie dla składni „[[nazwa]]” w celu definiowania atrybutów jak w C++ („[[gnu::const]]”, „[[deprecated]]”, „[[fallthrough]]”, „[[maybe_unused]]”, „[[nodiscard]]”, „[[noreturn]]”, „[[reproducible]]”, „[[unsequenced]]”). Na przykład, atrybut [[noreturn]] pozwala wskazać, że funkcja nie zwraca wartości (nagłówek stdnoreturn.h i specyfikator „_Noreturn” zostały uznane za przestarzałe).
- Wsparcie dla składni u8” w celu definiowania stałych z symbolami w UTF-8.
- Dodano typ char8_t dla ciągów i znaków w kodowaniu UTF-8 oraz funkcje do konwersji ciągów z wielobajtowymi symbolami mbrtoc8() i c8rtomb().
- Zmodyfikowano działanie słowa kluczowego „auto”, które teraz prowadzi do wnioskowania typu przy definiowaniu obiektów, co pozwala na użycie oznaczenia „auto” zamiast typu do określenia typu zmiennych na podstawie typu wyrażenia do ich inicjalizacji. Na przykład: „auto y = cos(x);”.
- Funkcje z pustą listą argumentów są teraz traktowane jako funkcje nieprzyjmujące argumentów.
- Dodano wsparcie dla nagłówków <stdckdint.h> i <stdbit.h> z makrami, funkcjami i typami do sprawdzania obliczeń całkowitych.
- Zezwolono na umieszczanie etykiet przejścia w dowolnych miejscach w ramach złożonych wyrażeń.
- Zakończono wsparcie dla trigrafów w kodzie, sekwencji trzech znaków ASCII przetwarzanych jako jeden znak, na przykład sekwencję «??=» można było używać zamiast «#». Po wprowadzeniu Unicode wsparcie dla trigrafów straciło sens.
- Dodano wsparcie dla prefiksów «0b» i «0B» do wskazywania wartości całkowitych w formie binarnej, na przykład «int b = 0b101010».
- Dodano słowa kluczowe bool, static_assert, alignas, alignof i thread_local.
- Zezwolono na podanie pustych nawiasów «{}» dla inicjalizacji na zerowe wartości, tzn. teraz można pisać «struct S { int x, y } s = {};».
- Udostępniono możliwość podawania dowolnych uniwersalnych nazw symboli w literach znakowych i ciągach. Na przykład, «int \u0024 = 0;».
- W «stddef.h» dodano makro «unreachable».
- Dodano nowy typ nullptr_t i stałą nullptr do określania zerowych wskaźników, które mogą być konwertowane na dowolny typ wskaźników i przedstawiać wariant NULL, niezwiązany z typami całkowitymi i typem void*. Na przykład, można podawać «void func(nullptr_t); func(0); func((void *)0);».
- Dodano typy «_BitInt (N)» oraz «unsigned _BitInt (N))» do określania liczb całkowitych z określoną liczbą bitów, a także dziesiętne typy zmiennoprzecinkowe «_Decimal32», «_Decimal64» i «_Decimal128» oraz funkcje do pracy z podobnymi typami.
- Dodano możliwość użycia znaku «‘» do czytelnego oddzielania cyfr w liczbach (na przykład, «1’000’000»).
- Struktury, unie i wyliczenia zezwalają na definiowanie więcej niż raz w jednym obszarze widoczności z tym samym zawartością i powtarzającym się tagiem.
- W standardzie dodano operatory typeof i typeof_unqual.
- Pojawiło się wsparcie dla użycia specyfikatora constexpr do definiowania obiektów.
- Do nagłówków float.h i math.h dodano makra INFINITY, NAN, FLT_NORM_MAX, DBL_NORM_MAX i LDBL_NORM_MAX.
- Dodano dyrektywy preprocesora #elifdef, #elifndef, #warning i #embed. «#embed» ma na celu integrację zasobów binarnych.
- Uproszczono użycie list z zmienną liczbą argumentów (variadic).
- Rozszerzono możliwości enumeracji (enum).
- Dodano wsparcie dla substytucji „%b” do przetwarzania wartości binarnych w rodzinach funkcji printf() i scanf().
- Wywołanie funkcji realloc() z zerowym rozmiarem zostało przekwalifikowane jako nieokreślone zachowanie.
- Funkcje memccpy(), strdup(), strndup(), gmtime_r() oraz localtime_r() zostały ustandaryzowane.
- Funkcje asctime() i ctime() zostały zadeklarowane jako przestarzałe.
- Makra static_assert i thread_local zostały przekwalifikowane jako słowa kluczowe.
Źródło: opennet.ru
