【问题标题】:Are main and fopen valid variable names?main 和 fopen 是有效的变量名吗?
【发布时间】:2014-09-17 13:04:47
【问题描述】:

C 标准规定变量名称不应与标准 C 关键字和标准函数名称匹配。那为什么下面的代码编译没有错误呢?

#include <stdio.h>

int main()
{
    int main = 10;
    printf("Magic is %d", main);
    return 0;
}

另见http://codepad.org/OXk4lZZE

在下面的answer 中,ouah 写道

main 不是保留标识符,允许命名变量 C中的main

那么考虑到下面的程序,这是否意味着fopen 同样没有被保留?

#include <stdio.h>

int main()
{
    int fopen = 10;
    printf("Magic is %d", fopen);
    return 0;
}

【问题讨论】:

  • C 标准说了很多事情......
  • 有趣的是,1984 年,一位 Sjoerd Mullender 在国际混淆 C 代码竞赛中采用了整个“main 作为全局变量”概念。看到它here

标签: c keyword


【解决方案1】:

你的程序是一个有效的 C 程序。

main 不是保留标识符,在 C 中可以将变量命名为 main

你不能做的是在文件范围内命名一个变量main,但这与其他与同名函数冲突的变量相同:

这是无效的:

int main = 0;

int main(void)
{
}

出于同样的原因,这是无效的:

int foo = 0;

int foo(void)
{
    return 0;
}

编辑:解决OP问题编辑,OP问题中的第二个程序也像C所说的那样有效

(C11, 7.1.3p1) “在以下任何子条款(包括未来的库方向)中具有外部链接的所有标识符和 errno 始终保留用作标识符 外部链接。”

fopen 变量标识符在示例程序中具有块作用域并且没有链接。

【讨论】:

  • 还要注意,因为你包含了&lt;stdio.h&gt;fopen 可能是一个函数样式的宏。那么它就不能作为某些类型的变量进行移植(“严格符合”),特别是像fopen(whatever) 这样调用的函数指针,因为这会扩展宏。如果实现没有将其定义为宏,或者如果您从未在 ( 之前立即编写变量名,它将作为变量名工作,所以这是一个很好的可移植性点......
  • 这与您已经给出的事实不同,标准库函数名称保留用于外部链接,因为即使您从未包含相关标头,该链接规则也适用。除了咨询保留的标识符和“未来方向”之外,无法通过任何方式可靠地解决问题。
  • @SteveJessop 这是一个有趣的观点,感谢您的评论。在将fopen 声明为int 的OP 示例中,fopen 可以在标头中定义为类似函数的宏这一事实没有发生。但是,使用函数指针类型和对指针的调用的不同示例确实会出现问题。
【解决方案2】:

默认情况下,全局变量和函数本质上是extern,而在块范围内,默认情况下它们是auto

要检查链接器如何解析符号,请检查here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多