標準Cは実在しない言語? GCCとClangの非互換性を暴く
Your C is not standard C
標準Cと現実のC(GCC/Clang + glibc/musl)の非互換性を列挙。asmが予約語でないためデフォルトでコンパイルエラーになる点、FLT_ROUNDSが実行時の丸めモードを反映しない点、C99から27年経ってもGCCが標準プラグマを無視する点、glibcのinitstateがPOSIXに反しNULLを返さない点、Clangが関数戻り値の修飾子を誤って扱う点、muslのva_startがC23の省略引数に対応しない点などを指摘。標準規格と実装の乖離を浮き彫りにする。
委員会は、誰も実際には使えない、使うことのない非現実的な言語を作り出した。
HNでの議論
43- omoikane
GCCが今も標準のプラグマを実装していないのを見ると、昔のGCCプラグマのイースターエッグを思い出す。これは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
- dzaima
> しかし、gccは常にFLT_ROUNDSを1と定義している
まあ、gccがFENV_ACCESSプラグマをサポートしておらず、そのためすべてのfesetround呼び出しが常に未定義動作であることを考えると、丸めモードがデフォルトから決して変わらないかのように振る舞うのは正当だよね :)
- MisterTea
Plan 9 Cを書くのが大好きで楽しんでいる者として言えるのは、「標準C」なるものは、今日では何を意味するにせよ、めちゃくちゃだということだ。挙げればきりがないが、唯一の2つのオープンソースコンパイラが肥大化した怪物であることから、C99以降の追加は無意味、インラインasmが移植性を台無しにし*、POSIXは地獄に落ちればいい(タイプライター端末も一緒に)。
C委員会に現在所属していて、実装済みおよび実装予定のすべての悪いアイデアのせいでおそらく辞めるだろう友人がいる。
* いや、ソースファイル中に何百万もの醜い#ifdefをばらまくのは気持ち悪くて読みにくい。コードを分割しろよ、まったく。
- Syzygies
…そして私はGoが標準Cだと思っていたよ!