#include<stdio.h>
void jigar (int ji)
{
printf("%d",ji);
}
void main()
{
int a=32;
(jigar)(a);
}
当我使用-Wall选项运行此程序时,编译器不会发出任何警告或错误,它可以正常工作。但是当我在 MIPS交叉编译工具链中编译该程序时,它会出错:
(jigar)(a);
在这一行。现在我的问题是:为什么gcc for linux并没有指出我的愚蠢错误?
答案 0 :(得分:3)
为什么(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
。
答案 1 :(得分:3)
(jigar)(a);
没有任何问题,因为它在标准C中是可以接受的.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条:
带括号的表达式是主表达式。 其类型和值与未表示的表达式相同。 左值,函数指示符,或者
如果未表示的表达式,则为空值表达式,左值,一个函数指示符,或无效表达。
P.S。有谁知道我在哪里可以获得ISO C的文档,如功能列表或什么?我见过有人引用它,但我自己找不到它。
答案 2 :(得分:1)
我在您的代码中看到的唯一错误是您的main
返回void
,而it should return int
。
gcc 4.4.3
-Wall
与(jigar)
选择了这一点。
如果你指的是{{1}}周围的括号,它是有效的C.如果你的MIPS编译器不喜欢它,那么它就是MIPS编译器的问题。