GCC error while binding functions

I have 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 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 is the conclusion

Hello World!!
1065353216
1065353216

If I build above, there is absolutely no error. It seems that when linking gcc , it doesn't matter that the two functions have different return types and different argument lists.

The second point is that in the show function, instead of performing an implicit conversion from float to int bit patterns are copied, and I checked them with a second printf call.

Why is this happening? I know this will not happen in g++ due to a name change, but is this not a serious problem?

+6
source share
2 answers

The trick is to declare your functions in the header file ( foo.h ), and then include this header file in the source file ( foo.c ). Also specify the header file in any source file (for example, main.c ) that calls the functions declared in foo.h.

Including foo.h in foo.c allows the compiler to verify that function declarations match function definitions. By including foo.h in main.c , let the compiler verify that main.c uses the functions correctly and also allows the compiler to do the necessary type conversions.

Lying to the compiler by falsely declaring functions in main.c is not good for you, as you know.

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; } 
+3
source

Implicit conversion will not occur because the code for the main file was generated using the declared caption. The answer is disassembly. also the conclusion that I received is "Hello world !! 1073741824 1065353216" which is located at a distance from you. Implicit conversion occurs at compile time. Binding is not the time for linkers to add an implicit conversion. both files are compiled with 2-digit signatures and they are compiled in their own domains, which do not require any conversion.

Dump the assembler code for the main function:

  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 

The end of the assembler dump. (gdb) disass show Dump the assembler code for the show function:

  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 
+1
source

All Articles