"test.h"
main.c:
#include <stdio.h>
#include "test.h"
int main() {
printf("%d\n", test);
}
при сборке программы с помощью компилятора TCC (tcc -std=c99 *.c) она собирается без проблем, и поведение у неё такое, как если бы в хедере я объявил переменную test с кейвордом extern. Однако при сборке компиляторами gcc или clang (gcc/clang -std=c99 *.c) они выдают ошибку в духе
/usr/bin/x86_64-pc-linux-gnu-ld.bfd: /tmp/b-6f8184.o:(.bss+0x0): multiple definition of `test'; /tmp/a-4c8426.o:(.data+0x0): first defined here
/usr/bin/x86_64-pc-linux-gnu-ld.bfd: /tmp/main-a41fcd.o:(.bss+0x0): multiple definition of `test'; /tmp/a-4c8426.o:(.data+0x0): first defined here
Вопрос: какой из компиляторов нарушает стандарт?
вопрос возник не на пустом месте. Дело в том, что скорее всего этот код должен собираться не только tcc, ибо я столкнулся с такой проблемой когда пытался собрать одну довольно старую софтину которая должна бы собираться на POSIX-совместимых OS, однако собралась она у меня только с TCC по той же самой причине, и я не думаю что разрабы этой софтины использовали TCC.
Скорее всего неправ tcc, потому что насколько я помню, если объявляешь переменную в глобал скоупе, по умолчанию она экстерн, в итоге у нас в глобал скоупе объявляются две переменные с одинаковым именем
ну таки если явно добавить кейворд extern в хедер, то всё начинает собираться и с gcc и с clang и с tcc
Потому что так и должно быть. extern как бы говорит "тут переменную с таким именем не ищи, она в другом transition unit'e, пусть линкер разбирается"
Держи, ты обосрался) For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage. If the declaration of an identifier for a function has no storage the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
Так и где я не прав? Тут сказано, если объявляем переменную без стораджа, то она экстернал. То есть в том кейсе мы в программе объявляем две экстернал переменные с одним именнм
Обсуждают сегодня