당신의 C는 표준 C가 아니다

Your C is not standard C

표준에 쓰인 C와 실제 gcc/clang + glibc/musl 환경의 C 사이에는 수많은 불일치가 존재한다. asm 키워드 처리, FLT_ROUNDS의 정적 정의, 27년째 무시되는 표준 pragma, initstate의 POSIX 위반, 함수 반환형 한정자 무시, musl의 구식 va_start 정의 등이 그 예로, 컴파일러가 기본 설정에서 표준을 얼마나 지키지 않는지 보여준다.

위원회는 아무도 실제로 사용하지 않을 비현실적인 언어를 만들어냈다.
  1. omoikane

    GCC가 아직도 표준 pragma를 구현하지 않는 걸 보면 예전 GCC pragma 이스터 에그가 떠오른다. 이건 gcc 0.9의 cccp.c에 있던 코드다:

    /*

    * the behavior of the #pragma directive is implementation defined.

    * this implementation defines it as follows.

    */

    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 ("You are in a maze of twisty compiler features, all different");

    }

    gcc 1.21에서는 사라졌다:

    #if 0

    /* This was a fun hack, but #pragma seems to start to be useful.

    By failing to recognize it, we pass it through unchanged to cc1. */

    ...

    #endif

  2. dzaima

    > gcc는 항상 FLT_ROUNDS를 1로 정의한다

    음, gcc가 FENV_ACCESS pragma를 지원하지 않고, 따라서 모든 fesetround 호출이 항상 UB라는 점을 고려하면, 반올림 모드가 기본값에서 절대 바뀌지 않는 것처럼 동작하는 것도 유효하다 :)

  3. MisterTea

    Plan 9 C를 쓰는 걸 좋아하고 즐기는 사람으로서 할 말은, 요즘 '표준 C'라는 게 뭘 의미하든 간에 그건 엉망이라는 거다. 이름을 대자면 너무 많은데, 유일한 두 오픈소스 컴파일러가 뚱뚱한 괴물이라는 것부터, c99 이후 추가된 것들이 무의미하다는 것, 인라인 asm이 이식성을 망친다는 것*, 그리고 POSIX는 불 속에서 죽어도 싸다(타자기 터미널이랑 같이).

    나한테는 지금 C 위원회에 있는 친구가 있는데, 이미 구현된 것과 앞으로 구현될 모든 나쁜 아이디어 때문에 아마 떠날 것 같다.

    * 아니, 소스 파일 전체에 못생긴 #ifdef를 백만 개 뿌리는 건 역겹고 읽기 힘들다. 코드를 좀 나눠라, 제발.

  4. Syzygies

    ...그리고 나는 Go가 표준 C인 줄 알았지!

이 날의 다른 글

2026-10-15