I have a program (main.c):
#include <stdio.h>
#include <math.h>
int main() {
int result = sqrt(9);
printf("result: %d\n" ,result);
return 0;
}
double sqrt(double blah) {
return 0;
}
When I run this, my result is
result: 3
This would tell me the linker is choosing the libm library's sqrt function instead of mine to call in my main function.
I don't get any errors or warnings when I compile this program with all warnings enabled:
gcc main.c -Wall
My questions:
- Why did the linker not choose my definition of
sqrtto call?- is this deterministic?
- Why did I not get any errors or warnings? It seems that multiple definitions of a function with the same signature is a gotcha that should be indicated somehow.
- Is there a way to output what functions were linked to where? So if I come across a case where the unexpected definition is referenced, I can debug?
The only thing I can think of is when I run gcc --precompile, I see this function declaration:
extern double sqrt(double);
Does this tell the linker that sqrt is defined outside of this file? And since this already satisfies the definition of sqrt, my own definition is ignored when linking?
gcc info (I know it is really clang, since I am on mac, not sure if that makes a difference in terms of this question)
gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Edit:
The assembly output:
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 15 sdk_version 10, 15
.section __TEXT,__literal8,8byte_literals
.p2align 3 ## -- Begin function main
LCPI0_0:
.quad 4621256167635550208 ## double 9
.section __TEXT,__text,regular,pure_instructions
.globl _main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movsd LCPI0_0(%rip), %xmm0 ## xmm0 = mem[0],zero
movl $0, -4(%rbp)
sqrtsd %xmm0, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -8(%rbp)
movl -8(%rbp), %esi
leaq L_.str(%rip), %rdi
movb $0, %al
callq _printf
xorl %esi, %esi
movl %eax, -12(%rbp) ## 4-byte Spill
movl %esi, %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
## -- End function
.globl _sqrt ## -- Begin function sqrt
.p2align 4, 0x90
_sqrt: ## @sqrt
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movsd %xmm0, -8(%rbp)
xorps %xmm0, %xmm0
popq %rbp
retq
.cfi_endproc
## -- End function
.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "result: %d\n"
.subsections_via_symbols