The C11 standards talk about the linkage of identifiers, but there is no obvious discussion about the rules of linking translation units. My question is brought up by compiling two simple examples using clang.
Here is my first example, which has two declarations of the same function but with incompatible types:
//testall.c
extern char myfun(void*);
int main(){
char a='c';
a=myfun(&a);
}
char myfun(char*c){
return *c;
}
Then I run the command: $clang -std=c11 testall.c
And clang reports an error:
testall.c:9:10: error: conflicting types for 'myfun'
char myfun(char*c){
^
testall.c:2:17: note: previous declaration is here
extern char myfun(void*);
^
1 error generated.
I understand this error, because the void pointer and pointer to char are incompatible types.
What confuses me is that when I separate the two declarations into two different translation units and then link them into one, clang doesn't report any error:
//test.c
extern char myfun(void*);
int main(){
char a='c';
a=myfun(&a);
}
// mylib.c
char myfun(char*c){
return *c;
}
Then I run this command: $clang -std=c11 test.c mylib.c.
clang compiles and links the two translation units without reporting any error or warning.
I was thinking that linking two translation units follows the rules in section 6.2.2 Linkages of identifiers of the C11 standards. But it seems that it is not the case. Can anyone help me to clarify it?
This is just undefined behaviour. C11 doesn't say anything about linkers or how they combine multiple translation units. In practice, this is not an issue since there would be a header file with function declaration for myfun() that's included the both of those C files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With