我并不是说这是一种很好的编程风格,但我很惊讶这已编译 [*] 并毫无怨言地运行:
#include <stdio.h>
// define function signature
typedef int (*proto_fn)();
int x() { return 22; }
// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn) {
printf("%d\n", proto_fn());
}
int main() {
printit(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
除了可能会混淆人类之外,C 标准中是否有任何内容禁止对类型和形式参数使用相同的名称?
[*](在这种情况下,Apple clang 版本 11.0.0 (clang-1100.0.33.8)。)
我修改了代码以检查该名称是否proto_fn代表proto_fn函数内的类型名称或该类型的变量printit。
#include <stdio.h>\n\n// define function signature\ntypedef int (*proto_fn)();\n\nint x() { return 22; }\n\n// Note: type name and formal parameter name are the same\nvoid printit(proto_fn proto_fn) \n{ \n printf("%d\\n", proto_fn());\n proto_fn;\n\n}\n\nint main() {\n printit(x);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n上面的代码工作正常。
\n#include <stdio.h>\n\n// define function signature\ntypedef int (*proto_fn)();\n\nint x() { return 22; }\n\n// Note: type name and formal parameter name are the same\nvoid printit(proto_fn proto_fn) \n{ \n printf("%d\\n", proto_fn());\n proto_fn kk;\n\n}\n\nint main() {\n printit(x);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n但此代码会引发错误:
\n error: expected \xe2\x80\x98;\xe2\x80\x99 before \xe2\x80\x98kk\xe2\x80\x99
\nproto_fn kk;
因此,由此我得出的结论是,名称proto_fn只是proto_fn函数内部类型的变量printit。我认为该类型proto_fn在函数内部不可见printit。我认为变量隐藏了函数内部的proto_fn类型。这可能就是代码有效的原因。proto_fnprintit