Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does GCC find printf ? My code worked without any #include

Tags:

c

I am a C beginner so I tried to hack around the stuff.

I read stdio.h and I found this line: extern int printf (const char *__restrict __format, ...);

So I wrote this code and i have no idea why it works.

code:

extern int printf (const char *__restrict __format, ...);

main()
{
    printf("Hello, World!\n");
}

output:

sh-5.1$ ./a.out 
Hello, World!
sh-5.1$ 

Where did GCC find the function printf? It also works with other compilers. I am a beginner in C and I find this very strange.

like image 211
luca112358 Avatar asked Sep 15 '25 16:09

luca112358


2 Answers

gcc will link your program, by default, with the c library libc which implements printf:

$ ldd ./a.out
        linux-vdso.so.1 (0x00007ffd5d7d3000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf2d307000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fdf2d4f0000)

$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep ' printf' | head -1
0000000000056cf0 T printf@@GLIBC_2.2.5

If you build your program with -nolibc you have to satisfy a few symbols on your own (see Compiling without libc):

$ gcc -nolibc ./1.c 
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x12): undefined reference to `__libc_csu_fini'
/usr/bin/ld: (.text+0x19): undefined reference to `__libc_csu_init'
/usr/bin/ld: (.text+0x26): undefined reference to `__libc_start_main'
/usr/bin/ld: /tmp/user/1000/ccCFGFhf.o: in function `main':
1.c:(.text+0xc): undefined reference to `puts'
collect2: error: ld returned 1 exit status

You need to understand the difference between the compile and link phases of program compilation.

In the compilation phase you describe to the compiler the various things you intend to call that may be in this file, in other files or in libraries. This is done using function declarations.

 int woodle(char*);

for example. This is what header files are full of.

If the function is in the same file then the compiler will work out how to call it while it compiles that file. But for other functions it leaves a note in the generated code that says

please wire up the woodle function here so I can call it.

Usually called an import and there are tools you can use to look at the imports in an object file - name depends on platform and toolset

The linkers job is to find those imports and resolve them. It will look at objects files passed on the command line, at libraries included on the command line and also standard libraries that the c standard says should be available to all programs.

In your printf case the linker found printf in the c standard library that the linker includes automatically.

BTW - the linker looks for 'exports' from objects and libraries, there are tools to look at those too. The linkers job is to match each 'import' to an 'export'

like image 31
pm100 Avatar answered Sep 18 '25 10:09

pm100



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!