在 C 和 C++ 的情况下,我对两个文件中相同函数和全局变量的不同声明有 2 个问题。
不同的函数声明
考虑以下代码片段:
文件_1.c
void foo(int a); int main(void) { foo('A'); }
文件_2.c
#include <stdio.h> void foo(char a) { printf("%c", a); //prints 'A' (gcc) }
正如我们所看到的,原型与位于 file_2.c中的定义不同,但是,该函数会打印预期值。
如果涉及到 C++,由于
foo(int)
链接时未定义引用,上述程序无效。它可能是由其他函数签名的存在引起的 - 与 C 相比,其中函数名称不包含任何指示函数参数类型的额外字符。但是当涉及到 C 时,那又如何呢?由于具有相同名称的原型具有相同的签名,无论参数的数量及其类型如何,链接器都不会发出错误。但是这里执行了哪些类型转换?它看起来像这样:
'A'
->int
-> 回到char
? 或者这种行为可能是未定义/实现定义的?全局变量的不同声明
我们有两个文件和同一个全局变量的两个不同声明:
文件_1.c
#include <stdio.h> extern int a; int main(void) { printf("%d", a); //prints 65 (g++ and gcc) }
文件_2.c
char a = 'A';
在 C 和 C++ 中,输出都是 65。
虽然我想知道这两个标准对这种情况的看法。
在 C11 标准中,我发现了以下片段:
J.5.11 多个外部定义 (附件 J.5 通用扩展)
一个对象的标识符可能有多个外部定义,无论是否显式使用关键字 extern;如果定义不一致,或者不止一个被初始化,则行为未定义(6.9.2)。请注意,它指的是存在两个或多个定义,在我的代码中只有一个,所以我不确定这篇文章在这种情况下是否是一个很好的参考点......