简体   繁体   中英

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);
}

When I run this program with the -Wall option, the compiler doesn't give any warning or error, it works fine. But when I compile this program in MIPS cross-compiler tool chain , then it gives an error:

(jigar)(a);

at this line. Now my question is: why gcc for linux doesn't point out my silly mistake?

why does not give warning or error?

That's a perfectly acceptable construct for a Standard C conformant compiler (which I'm not claiming gcc is).
That's just a pair of extra redundant parenthesis around the function name, resolving to the same thing as the function name by itself ... or surrounded by even more parenthesis.

/* assuming `jigar` is a honest-to-God function
** all 3 statements below "do" the same thing */
jigar(a);
(jigar)(a);
(((((((jigar)))))))(a);

I've seen it used in real-life to prevent macro expansion (the example was made up right now though).

#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;
}

You can see the code above running on codepad and on ideone .

And main returns int , not void .

There's nothing wrong with (jigar)(a); as it is acceptable in standard C. The reason your MIPS compiler gives warning is because perhaps that compiler does not fully implement standard C.

Edit: Regarding Als's request for why this is standard C, here's how:

Look at the ISO C grammar here: http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/notation/c.html and note that a function call

postfix-expression -> postfix-expression ( )
                    | postfix-expression ( argument-expression-list )

can have postfix-expression as function. There is a rule that says:

postfix-expression -> primary-expression

where primary-expression could be an identifier , that is function name. However there is also this rule:

primary-expression -> ( expression )

and if you follow the chain of rules from expression you get back at primary-expression again. Therefore indirectly, you have:

primary-expression -> ... -> ( primary-expression ) -> ( identifier )

The semantics of C indicates that ( expression ) has the same type and value as expression (1). According to the grammar, (jigar)(a) is correct. Semantically, (jigar) and jigar have the same type and value. Therefore C accepts (jigar)(a) and the functionality is the same as jigar(a) .

Edit 2:

(1) C99 draft section 6.5.1 article 5:

A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression . It is an lvalue, a function designator , or a void expression if the unparenthesized expression is , respectively, an lvalue, a function designator , or a void expression.

PS anyone knows where I can get the documentation for ISO C, like a list of features or something? I have seen people quote it, but I couldn't find it myself.

The only error that I see in your code is that your main returns void , whereas it should return int .

gcc 4.4.3 with -Wall picks this up.

If you're referring to the parentheses around (jigar) , it's valid C. If your MIPS compiler doesn't like it, then it's a problem with the MIPS compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM