为什么这个程序不会产生任何警告?

时间:2011-09-19 12:03:47

标签: c linux warnings mips

#include<stdio.h>
void jigar (int ji)
{
    printf("%d",ji);
}
void main()
{
int a=32;
(jigar)(a);
}

当我使用-Wall选项运行此程序时,编译器不会发出任何警告或错误,它可以正常工作。但是当我在 MIPS交叉编译工具链中编译该程序时,它会出错:

(jigar)(a);

在这一行。现在我的问题是:为什么gcc for linux并没有指出我的愚蠢错误?

3 个答案:

答案 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;
}

您可以在codepadideone上看到上面的代码。

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编译器的问题。