views:

173

answers:

3

Yesterday, I have been watching discussion here, about compilers and linkers. It was about C library function definitions. I have never thought of that, so it inspired me to do some searching, but I cannot find exactly what I want. I wonder, what is the smallest syntax you need to add into your source code to enable just printf() function. I mean the function declaration from stdio.h you need.

+1  A: 

The definition is usually compiled in a shared library. The declaration is what you need. Not having a declaration in scope invokes undefined behavior. So, for every library, you'd typically have a (set of) header file(s) and the compiled binary shared/static library. You compile your sources by including appropriate headers and link with the library. To bring in the declaration in scope use the #include directive. E.g. for printf you'd do:

#include <stdio.h>
int main() {
    printf("Hello, world\n");
    return 0;
}

But then any decent book on C or C++ should already cover this in detail and with better examples.

dirkgently
Is there a way to see actual definitions of these functions? In C or ASM code?
Vit
+4  A: 

The C99 declaration of printf() is

int printf(const char *restrict, ...);

but most compilers will also accept

int printf(const char *, ...);    

See also C99 section 7.1.4, §2:

Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.

Note: In this case, the restrict qualifier combined with const promises the compiler that the format string is never modified within printf(), even if the pointer is passed again as one of the variadic arguments.

Christoph
@David: `restrict` is not the argument name, but one of the three C99 type qualifiers (the others are `const` and `volatile`)
Christoph
I didn't know that, thanks for the clarification.
David Rodríguez - dribeas
@Christoph: Actually, `restrict` means the compiler can ignore aliasing and you *cannot* pass the format string again as a variadic argument. If you do pass it twice, that's undefined behavior; see 6.7.3.1/4 in the C standard.
Roger Pate
@Roger: I thought so too (check my edits on the answer), but that's wrong: 6.7.3.1, example 3 explicitly shows that two `restrict` arguments may alias each other as long as the pointed-to object isn't modified within the function, which `printf()` doesn't do, ie `printf(foo, foo)` should be legal!; you can't see from the declaration alone whether it's legal to pass in aliased pointers
Christoph
@Christoph: I actually deciphered (or thought I did) /4 to double check before posting, but then you had to go and ruin it with a mere *example*.
Roger Pate
@Roger: the reason for this somewhat confusing definition is that `restrict` isn't there to make promises to the _caller_ (as a `const` would do), but to allow further optimizations within the _callee_ ; only when you combine these qualifiers (ie `const *restrict`) you're able to deduce further information from the declaration alone
Christoph
A: 

It depends on your compiler and platform.

On most cases just declaring

int printf(const char *, ...);

will just do, however, your particular compiler/platform or C library implementation even can change this declaration, for calling convention purposes.

All in all it is not worth it to try and declare things yourself, as this could be a violation of the one definition rule. You should always include the apropriate header, stdio.h(cstdio for C++) in this case.

Ramon Zarazua
It´s just for learning purposes...
Vit