Reputation: 4609
I've the following two .c
files
main.c
#include <stdio.h>
int print();
int show(int);
int main()
{
int i = 0;
float x = 1.0;
int y = *((int*)(&x));
print();
i = show(5);
printf("%d", i);
printf("\n%d", y);
return 0;
}
foo.c
#include <stdio.h>
void print()
{
printf("Hello World !!\n");
}
float show()
{
return 1;
}
And here's is my makefile
CC = gcc
CFLAGS = -I. -Wall -pedantic -Wconversion
.PHONY: clean
%.o: %.c
$(CC) -c -o $@ $< $(CFLAGS)
main: main.o foo.o
$(CC) -o main main.o foo.o $(CFLAGS)
clean:
rm -rf *.o
rm -rf main
Here's the output
Hello World !!
1065353216
1065353216
If I build the above, there is absolutely no error. It seems while linking gcc
doesn't care that the two functions have different return types and different argument lists.
The second point is that in the function show
instead of doing an implicit conversion from float
to int
, the bit patterns are getting copied, which I've verified using the second printf
call.
Why is the above happening? I know this won't happen in g++
due to name mangling, but isn't this a serious problem?
Upvotes: 6
Views: 352
Reputation: 34839
The trick is to declare your functions in a header file (foo.h
) and then include that header file in the source file (foo.c
). Also include the header file in any source file (e.g. main.c
) that calls the functions declared in foo.h.
Including foo.h
in foo.c
allows the compiler to verify that the function declarations match the function definitions. Including foo.h
in main.c
let's the compiler verify that main.c is using the functions correctly, and also allows the compiler to make any necessary type conversions.
Lying to the compiler, by falsely declaring the functions in main.c, does you no good, as you found out.
foo.h
void print( void );
float show( void );
main.c
#include <stdio.h>
#include "foo.h"
int main()
{
int i = 0;
print();
i = show();
printf("%d\n", i);
return 0;
}
foo.c
#include <stdio.h>
#include "foo.h"
void print( void )
{
printf("Hello World !!\n");
}
float show( void )
{
return 2;
}
Upvotes: 3
Reputation: 379
implicit conversion will not happen as the code for main was generated using the signature on top declared. answer lies in disassembly. also output i got is "Hello World !! 1073741824 1065353216" which is diif from yours. Implicit conversion happens at compile time. Linking is not the time for linkers to add implicit conversion. both files are compiled with 2 diff signatures and they are compiled in their own domains not requiring any conversion.
Dump of assembler code for function main:
0x0000000000400504 <+0>: push %rbp
0x0000000000400505 <+1>: mov %rsp,%rbp
0x0000000000400508 <+4>: sub $0x10,%rsp
0x000000000040050c <+8>: movl $0x0,-0x8(%rbp)
0x0000000000400513 <+15>: mov $0x3f800000,%eax
0x0000000000400518 <+20>: mov %eax,-0xc(%rbp)
0x000000000040051b <+23>: lea -0xc(%rbp),%rax
0x000000000040051f <+27>: mov (%rax),%eax
0x0000000000400521 <+29>: mov %eax,-0x4(%rbp)
0x0000000000400524 <+32>: mov $0x0,%eax
0x0000000000400529 <+37>: callq 0x400570 <print>
0x000000000040052e <+42>: mov $0x5,%edi
0x0000000000400533 <+47>: callq 0x400580 <show>
0x0000000000400538 <+52>: mov %eax,-0x8(%rbp)
0x000000000040053b <+55>: mov $0x400698,%eax
0x0000000000400540 <+60>: mov -0x8(%rbp),%edx
0x0000000000400543 <+63>: mov %edx,%esi
0x0000000000400545 <+65>: mov %rax,%rdi
0x0000000000400548 <+68>: mov $0x0,%eax
0x000000000040054d <+73>: callq 0x4003f0 <printf@plt>
0x0000000000400552 <+78>: mov $0x40069b,%eax
0x0000000000400557 <+83>: mov -0x4(%rbp),%edx
0x000000000040055a <+86>: mov %edx,%esi
0x000000000040055c <+88>: mov %rax,%rdi
0x000000000040055f <+91>: mov $0x0,%eax
0x0000000000400564 <+96>: callq 0x4003f0 <printf@plt>
0x0000000000400569 <+101>: mov $0x0,%eax
0x000000000040056e <+106>: leaveq
0x000000000040056f <+107>: retq
End of assembler dump. (gdb) disass show Dump of assembler code for function show:
0x0000000000400580 <+0>: push %rbp
0x0000000000400581 <+1>: mov %rsp,%rbp
0x0000000000400584 <+4>: mov $0x40000000,%eax
0x0000000000400589 <+9>: mov %eax,-0x4(%rbp)
0x000000000040058c <+12>: movss -0x4(%rbp),%xmm0
0x0000000000400591 <+17>: leaveq
0x0000000000400592 <+18>: retq
Upvotes: 1