GCC 15 ломает код сишникам
Привет, ЛОР!
Из-за того, что GCC по умолчанию переходит на стандарт C23 для компилируемого кода, возникли некоторые интересные нюансы. Так например, начиная с C23 пустой список аргументов у функции теперь будет считаться объявлением с void
. То есть, следующие два объявления будут эквивалентными:
void f1() { }
void f2(void) { }
Это крохотное изменение внезапно сломало вагон и маленькую тележку программ под Linux, где используется этот трюк для передачи в функцию по указателю различных аргументов:
typedef int (*fptr)();
int f1(void) { return 1; }
int f2(int a) { return 2 + a; }
int main(void) {
fptr f;
int r = 0;
f = f1;
r += f();
f = f2;
r += f(1);
return r;
}
Подобный код больше не будет собираться. Сломанными оказались такие программы как: Linux (ядро), bash, iwd, samba, bluez, rustc, gnupg, vde2, sudo, gdb, postgresql, guile, w3m, freeglut, neovim, dnsmasq и куча других.
Бонусом к этому будет добавленный в mbedtls (и не только) баг, вызванный иным порядком инициализации union.
int main() {
union {
int dummy;
struct { int fs[4]; } s;
} v = { 0 };
printf("%d\n", v.s.fs[3]);
return 0;
}
В gcc 14 и ранее код выведет 0, начиная с gcc 15 – мусор.
Плюс ко всему, bool, true и false теперь ключевые слова, что тоже ломает кучу кода. В общем, сишников ждут интересные времена и много работы по исправлению костылей. Возрадуемся же!
За наводку можно поблагодарить забавнишегося sf: