Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is gcc doing implicit function declarations incorrectly in c99 mode?

Consider the following code:

int main (void) {
    int i = xyzzy();
    return i;
}
int xyzzy (void) {
    return 42;
}

Now, although the prototype for xyyzy is unkown at the point of use, this works in c89 mode because the default return type of a function that has no prototype is int so the implicit function prototype and actual function are compatible.

And, in fact, if you change the return type of the function to float, you get (as expected):

testprog.c:6: error: conflicting types for 'xyzzy'
testprog.c:2: error: previous implicit declaration of 'xyzzy' was here

because the implicit prototype and actual function no longer match.

The original code compiled with gcc --std=c89 --pedantic -Wall -Wextra only gives me the warning:

testprog.c: In function 'main':
testprog.c:2: warning: implicit declaration of function 'xyzzy'

which is expected, because c89 has this to say in 3.7.1 Function definitions:

extern int max(int a, int b) { ... }: Here extern is the storage-class specifier and int is the type specifier (each of which may be omitted as those are the defaults).

and in 3.3.2.2 Function calls:

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration extern int identifier(); appeared.

So the use of a function before declaring it definitely results in the default prototype being created.


However, both those phrases have been removed in c99 and we instead find in 6.5.2.2 Function calls (my bold):

If the expression that denotes the called function has type pointer to function returning an object type, the function call expression has the same type as that object type, and has the value determined as specified in 6.8.6.4. Otherwise, the function call has type void.

I understand it to mean that, if there's no declaration in view when you try to call a function, it's implicitly declared with a void return type.

Yet, when compiling with gcc --std=c99 --pedantic -Wall -Wextra, I get just the same warning about the implicit declaration.

Shouldn't c99 have declared that function implicitly as returning void? If it had, I would have expected a previous implicit declaration error similar to the one I got when I tried to redeclare it as returning float.

Is gcc broken here, or am I missing something in the standard?

like image 818
paxdiablo Avatar asked Dec 21 '12 07:12

paxdiablo


People also ask

What is implicit declaration of function in c99?

9/30/2020. NKurzman. First you have the Option to tell the compiler to use C90 ode. implicit declaration of function means you do not have Prototypes for your functions. You should have a Prototype before the function is used.

Why is implicit declaration error in C?

Such an 'implicit declaration' is really an oversight or error by the programmer, because the C compiler needs to know about the types of the parameters and return value to correctly allocate them on the stack.

How do you correct an implicit declaration of a function?

Function name typo: Often the function name of the declaration does not exactly match the function name that is being called. For example, startBenchmark() is declared while StartBenchmark() is being called. I recommend to fix this by copy-&-pasting the function name from the declaration to wherever you call it.

What is implicit declaration?

If a name appears in a program and is not explicitly declared, it is implicitly declared. The scope of an implicit declaration is determined as if the name were declared in a DECLARE statement immediately following the PROCEDURE statement of the external procedure in which the name is used.


1 Answers

You are reading the standard incorrectly. There's no such thing as implicit function declaration in C. It is removed from the language by C99.

GCC issues a warning when it sees an erroneous construct that looks like an implicit function declaration. This is OK as far as the standard is concerned. The standard requires a diagnostic here, and a warning is a diagnostic. You may use -Werror=implicit-function-declaration flag to GCC to turn this into an error.

like image 62
n. 1.8e9-where's-my-share m. Avatar answered Sep 23 '22 20:09

n. 1.8e9-where's-my-share m.