On k&r 2nd edition p123, it shows the grammar of declarator enter image description here

I've found similar syntax on c standard n1256 enter image description here

根据这int foo()()()也是一个有效的声明(这显然不是),我在这里遗漏了什么?

ps:有一个cdecl site,它将c声明破译为简单的单词,它将decl上面的内容翻译为"declare foo as function returning function returning function returning int"

推荐答案

根据你引用的语法规则,int foo()();是一个syntactically有效的声明.然而,它是semantically无效的;它不符合6.7.6.3p1中的约束[C11/N1570;可能在您正在阅读的不同位置].

6.7.6.3函数声明符(包括原型)

Constraints

  1. 函数声明符不应指定函数类型或数组类型的返回类型.

这是一条语义规则,而不是语法规则,因为这样更容易编写标准.在句法上禁止T name ( ... ) ( ... )甚至可能不是LR(1) grammar中的possible.(C的语法tries是LR(1),尽管我记得它没有完全实现它.)如果可能的话,它仍然会使direct-declarator的定义变得复杂得多.T name ( ... ) ( ... )并不是[try ]声明返回类型为函数类型的函数的唯一方法.语义约束在一句话中涵盖了所有的可能性.

只有当您自己编写C解析器时,语义规则和语法规则之间的差异才重要.如果您只是想了解什么是有效的C程序,什么是无效的C程序,那么int foo()();无论是哪种方式都是无效的.

如果您试图理解什么是有效的C程序by reading the text of the C standard,什么不是有效的C程序by reading the text of the C standard,您应该知道C标准从来不会说编译器must会为某些东西发出硬错误.如果做不到这一点,实施者通常采用5.1.1.3的第一句话来定义警告和错误之间的界限:

如果预处理翻译单元或翻译单元包含违反任何syntax ruleconstraint的情况,则符合性实现应产生至少一个诊断消息(以实现定义的方式标识

(黑体字:我的强调).所以,你需要阅读语法规则和所有"约束"部分的文本.

C++相关问答推荐

错误:在.h程序中重新定义 struct

如何启用ss(另一个调查套接字的实用程序)来查看Linux主机上加入的多播组IP地址?

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

编译SDL 2时缺少SDL_ttf

不会停在空格或换行符上的错误

在c++中使用堆栈的有效括号

为什么GCC C23中的关键字FALSE不是整数常量表达式?

X86/x64上的SIGSEGV,由于原始内存访问和C中的DS寄存器之间的冲突,在Linux上用TCC编译为JIT引擎

Sizeof(&Q;字符串&Q;)的正确输出是什么?

Vcpkg的配置文件

无法在OpenGL上绘制三角形

这个计算C中阶乘的函数正确吗?

如何只获取字符串的第一个单词,然后将其与c中的另一个单词进行比较?

变量的作用域是否在C中的循环未定义行为或实现定义行为的参数中初始化?

如何对现有的双向循环链表进行排序?

生成的头文件不包括用户定义的文件

在git补丁中自动添加C的宏

atoi函数最大长-长误差的再创造

System V 消息队列由于某种原因定期重置

`void foo(int a[static 0]);` 有效吗?