Reputation: 925
Sorry for the bad title, hopefully my explanation is clearer.
I have the following c
program:
clang_test.c
#include "clang_test2.c"
int main()
{
somefunc();
return 0;
}
clang_test2.c
int somefunc()
{
return 5;
}
I then compile it using clang with the -E
parameter in order to see the result of the preprocessor.
clang.exe -std=c99 -pedantic-errors -E .\clang_test.c
The preprocessor output is this:
# 1 ".\\clang_test.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 324 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 ".\\clang_test.c" 2
# 1 "./clang_test2.c" 1
int somefunc()
{
return 5;
}
# 3 ".\\clang_test.c" 2
int main()
{
somefunc();
return 0;
}
This works as expected and I get no compilation error if I try to compile it regularly without -E
.
For the sake of experimentation I modified clang_test.c
to not #include clang_test2.c
:
int main()
{
somefunc();
return 0;
}
I then tried to compile using:
clang.exe -std=c99 -pedantic-errors .\clang_test2.c .\clang_test.c
And I get a compiler error saying:
.\clang_test.c:13:2: error: implicit declaration of function 'somefunc' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
somefunc();
But if I look at the output of the preprocessor, it seems like it should work because somefunc()
is still declared above the main
function where it's used:
# 1 ".\\clang_test2.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 324 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 ".\\clang_test2.c" 2
int somefunc()
{
return 5;
}
# 1 ".\\clang_test.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 324 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 ".\\clang_test.c" 2
int main()
{
somefunc();
return 0;
}
So based on this observation, is it not reliable to look at the output of the preprocessor in order to diagnose problems related to function definitions/declarations? And also since the only difference between the 2 preprocessor outputs is this block of text:
# 1 ".\\clang_test.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 324 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 ".\\clang_test.c" 2
What could it be doing to prevent somefunc()
from being properly forward declared?
Upvotes: 0
Views: 84
Reputation: 46990
The line
clang.exe -std=c99 -pedantic-errors .\clang_test2.c .\clang_test.c
does not just concatenate the two files and compile them. It compiles each of the C files separately to object (.o
) files and then links them. You get the error because compiled alone,
int main()
{
somefunc();
return 0;
}
doesn't define somefunc
. You'll need a prototype to tell the compiler its type:
int somefunc(void);
int main(void)
{
somefunc();
return 0;
}
Note that you should be using proper prototypes throughout. Functions with no arguments should be be declared with void
argument lists. Old style function interfaces (e.g. with arg lists ()
) allow many kinds of errors that prototypes allow the compiler to detect.
On the other hand the output of the compiler with -E
clang.exe -std=c99 -pedantic-errors -E .\clang_test2.c .\clang_test.c
does concatenate the two files and send them through the C preprocessor. The difference - compiling to object and liking vice concatenating - explains the behaviors you see.
Upvotes: 1