众所周知,函数和变量不能共享同一个名称
像这样:
#include<stdio.h>
int main;
int main()
{
return 0;
}
这是由"main"重新声明为不同类型的符号引起的
但以下两个文件可以成功编译,这让我感到困惑。main.c:
void print_main(void);
int main() {
print_main();
return 0;
}
print_main.c
#include <stdio.h>
char main;
void print_main() {
printf("Output: 0x%xn", main); //Output: ffffffe9
}
困惑
- 我想知道编译器为什么不提醒我"main"重新声明为不同类型的符号
- 为什么我得到一个奇怪的数字";ffffff e9";它是什么
- 为什么当我在另一个IDE上运行这些文件时,奇怪的数字发生了变化
我尝试了什么
- 事实上,我知道这是由全局变量"引起的;主";并且函数";main(("具有相同的名称
所以,这里发生了一些有趣的事情 - 在Visual Studio 2019上编译并运行它;ffffff e9">
但是在CLion上编译并运行它,输出将是";0x55"> - 当我试图检查变量"的地址时;"main"我发现它与函数"的地址相同;main((">
像这样
main.c
void print_main(void);
int main() {
printf("%pn", &main); // 003D12BC
print_main();
return 0;
}
print_main.c
#include <stdio.h>
char main;
void print_main() {
printf("Output: %xn", main); //ffffffe9
printf("%pn", &main); //003D12BC
}
几天前我似乎基本上回答了同样的问题。哦,等等,我做到了。如果对方的OP接受了答案,我会把现在的问题当作一个骗局来结束。
摘要:
-
一致性编译器必须在一个翻译单元中诊断同一标识符的不兼容声明,但对于不同翻译单元中的声明,不需要诊断该问题。
-
在任何一种情况下,一致性编译器都不需要拒绝程序,无论它是否发出诊断,但如果它接受诊断,则程序具有未定义的行为。
- 我想知道编译器为什么不提醒我"main"被重新声明为不同类型的符号
它没有义务这样做(见上文(,单独的编译使这样做具有挑战性。归根结底,这是一个实现质量问题。
- 为什么我得到一个奇怪的数字"ffffff e9";它是什么
两个词:未定义的行为。
- 当我在另一个IDE上运行这些文件时,为什么奇怪的数字发生了变化
再次:未定义的行为。
尝试深入研究程序未定义行为在不同C实现中的各种表现方式并没有多大用处。相反,编写行为定义良好的程序。特别是不要编写那些您知道行为未定义的程序。