[英]Why doesn't this program produce any warning?
#include<stdio.h>
void jigar (int ji)
{
printf("%d",ji);
}
void main()
{
int a=32;
(jigar)(a);
}
当我使用-Wall选项运行该程序时,编译器不给出任何警告或错误,它可以正常工作。 但是,当我在MIPS交叉编译器工具链中编译该程序时,则会出现错误:
(jigar)(a);
在这一行。 现在我的问题是:为什么Linux的gcc不能指出我的愚蠢错误?
为什么(jigar)(a); 没有给出警告或错误?
对于符合标准C的编译器(我并不是说gcc
是这样),这是一个完全可以接受的构造。
那只是围绕函数名称的一对多余的括号,单独解决了与函数名称相同的问题……甚至被更多的括号所包围。
/* assuming `jigar` is a honest-to-God function
** all 3 statements below "do" the same thing */
jigar(a);
(jigar)(a);
(((((((jigar)))))))(a);
我已经看到它在现实生活中用于防止宏扩展(尽管该示例现在已完成)。
#include <stdio.h>
#define MACRO(x) ((x) - 42)
int (MACRO)(int x) { return 42 + x; } /* does not expand MACRO! */
int main(void) {
printf(" MACRO ==> %d\n", MACRO(100)); /* expand */
printf("(MACRO) ==> %d\n", (MACRO)(100)); /* do not expand */
return 0;
}
并且main
返回int
,而不是void
。
(jigar)(a);
没什么错(jigar)(a);
MIPS编译器发出警告的原因是,也许是因为编译器没有完全实现标准C。
编辑:关于Als为何是标准C的要求,方法如下:
在此处查看ISO C语法: http : //www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/notation/c.html,并注意函数调用
postfix-expression -> postfix-expression ( )
| postfix-expression ( argument-expression-list )
可以将postfix-expression
作为函数。 有一条规则说:
postfix-expression -> primary-expression
其中primary-expression
可以是一个identifier
,即函数名。 但是,还有以下规则:
primary-expression -> ( expression )
如果您遵循expression
的规则链,则会再次回到primary-expression
。 因此,间接地,您具有:
primary-expression -> ... -> ( primary-expression ) -> ( identifier )
C的语义表明( expression )
与expression
(1)具有相同的类型和值。 根据语法,(jigar)(a)是正确的。 在语义上, (jigar)
和jigar
具有相同的类型和值。 因此,C接受(jigar)(a)
,并且功能与jigar(a)
相同。
编辑2:
(1)C99第6.5.1条第5条草案:
带括号的表达式是主要表达式。 其类型和值与非括号表达式相同 。 它是一个左值, 函数指示符 ,或空隙表达式如果加括号的表达是 ,分别左值, 功能指示符 ,或空隙表达。
PS谁知道我可以从哪里获得ISO C文档,例如功能列表或其他内容? 我见过有人引用它,但我自己找不到。
我在您的代码中看到的唯一错误是您的main
返回void
,而应返回int
。
带有-Wall
gcc 4.4.3
对此进行了说明。
如果您指的是(jigar)
括号,则它是有效的C。如果您的MIPS编译器不喜欢它,则说明MIPS编译器存在问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.