Ваш C — не стандартный C: компиляторы игнорируют стандарт

Your C is not standard C

Автор перечисляет несоответствия между стандартным C и тем, что на самом деле поддерживают gcc, clang и glibc/musl. Среди примеров: ключевое слово asm не зарезервировано в стандарте, но распознаётся компиляторами по умолчанию; FLT_ROUNDS всегда равен 1 в gcc, несмотря на требования стандарта; стандартные прагмы C99 и C23 остаются no-op в gcc спустя 27 лет; initstate в glibc не возвращает NULL при ошибке вопреки POSIX; clang считает квалификаторы в возвращаемом типе значимыми; а musl предоставляет устаревшее определение va_start, блокирующее C23.

Комитет создал нереальный язык, который никто не может и не будет использовать.
  1. omoikane

    То, что GCC до сих пор не реализует стандартные прагмы, напоминает мне старую пасхалку с прагмами в GCC. Вот фрагмент из cccp.c в gcc 0.9:

    /*

    * поведение директивы #pragma определяется реализацией.

    * данная реализация определяет его следующим образом.

    */

    do_pragma ()

    {

    close (0);

    if (open ("/dev/tty", O_RDONLY) != 0)

    goto nope;

    close (1);

    if (open ("/dev/tty", O_WRONLY) != 1)

    goto nope;

    execl ("/usr/games/hack", "#pragma", 0);

    execl ("/usr/games/rogue", "#pragma", 0);

    execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);

    execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);

    nope:

    fatal ("Вы в лабиринте извилистых возможностей компилятора, все разные");

    }

    В gcc 1.21 это уже исчезло:

    #if 0

    /* Это был забавный хак, но #pragma, похоже, начинает быть полезным.

    Не распознавая его, мы передаём его без изменений в cc1. */

    ...

    #endif

  2. dzaima

    > gcc, однако, всегда определяет FLT_ROUNDS как 1

    Ну, учитывая, что gcc не поддерживает прагму FENV_ACCESS, и, следовательно, все вызовы fesetround всегда являются UB, он имеет право вести себя так, как будто режим округления никогда не меняется с значения по умолчанию :)

  3. MisterTea

    Как человек, который любит и наслаждается написанием кода на Plan 9 C, могу сказать только одно: «стандартный C», что бы это ни значило сегодня, — это бардак. Слишком много всего, чтобы перечислять: начиная с того, что единственные два open-source компилятора — это раздутые монстры, добавления после C99 бессмысленны, встроенный ассемблер убивает переносимость*, а POSIX может сгореть в аду (вместе с печатными терминалами).

    У меня есть друг, который сейчас в комитете по C и, вероятно, уйдёт из-за всех плохих идей, которые уже реализованы и будут реализованы.

    * Нет, закидывание миллионом уродливых #ifdef по всем исходникам — это мерзко и трудночитаемо. Разделите код, чёрт возьми.

  4. Syzygies

    ...а я-то думал, что Go — это стандартный C!

Ещё за этот день

2026-10-15