我的代码在 Linux 上编译时工作正常,但在 Windows 上的 MinGW 上失败。
\n我正在将这四个文件编译在一起。 a.h是头文件,b.c,c.c和main.c. 以下是内容。
\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80> cat a.h\nenum {\n BLACK,\n WHITE\n} Colors;\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80> cat b.c\n#include "a.h"\n#include <stdio.h>\n\nvoid foo() {\n printf("%d\\n", BLACK);\n}\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80> cat c.c\n#include "a.h"\n#include <stdio.h>\n\nvoid bar() {\n printf("%d\\n", WHITE);\n}\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80> cat main.c\nvoid foo();\nvoid bar();\n\nint main() {\n foo();\n bar();\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n我用这个命令编译它们:
\ngcc -c b.c; gcc -c c.c; gcc -c main.c; gcc -o colors b.o c.o main.o\nRun Code Online (Sandbox Code Playgroud)\n它在我的 Linux 桌面上运行良好,但在MinGW VM上失败。错误是:
\n# gcc -c b.c; gcc -c c.c; gcc -c main.c; gcc -o colors b.o c.o main.o\nC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c.o:c.c:(.bss+0x0): multiple definition of `Colors\'; b.o:b.c:(.bss+0x0): first defined here\ncollect2.exe: error: ld returned 1 exit status\nRun Code Online (Sandbox Code Playgroud)\n当我在 Linux 上运行时nm,b.o我看到:
\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80> nm b.o\n0000000000000004 C Colors\n0000000000000000 T foo\n U printf\nRun Code Online (Sandbox Code Playgroud)\n但在 MinGW 上,我看到了这一点:
\n0000000000000004 B Colors\nRun Code Online (Sandbox Code Playgroud)\n不知何故,gcc 在每个系统上以不同的方式编译它们。那里B意味着我不能两次使用相同的符号,尽管在 Linux 上我得到了C并且它工作得很好。从联机帮助页来看nm:
"B"\n "b" The symbol is in the uninitialized data section (known as BSS).\n\n "C" The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with\n the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references.\nRun Code Online (Sandbox Code Playgroud)\n我该如何解决这个问题以便能够在 MinGW 上进行编译?
\nLinux 使用 GCC 9;MinGW 可能使用 GCC 10。
\n您似乎创建了一个名为Colors未标记enum类型的变量:
enum {
BLACK,
WHITE
} Colors;
Run Code Online (Sandbox Code Playgroud)
您可能只想声明一个enum带有 tag 的类型Colors:
enum Colors {
BLACK,
WHITE
};
Run Code Online (Sandbox Code Playgroud)
如果前者包含在多个源文件中,则它是无效的 C,因为它会产生Colors. 这是允许的,但不要求产生错误;不同系统的目标文件格式如何表示未初始化的全局变量导致其在链接时被检测为错误或不被检测为错误的实现细节。现代 GCC 即使在支持公共资源的目标上也不再使用公共资源,因此如果您更新到足够新的 GCC,这在 Linux 上也会出现错误。