Issue
I found these lines in a header file (https://github.com/eyalroz/printf/blob/master/src/printf/printf.h) that is part of a printf
implementation.
// If you want to include this implementation file directly rather than
// link against, this will let you control the functions' visibility,
// e.g. make them static so as not to clash with other objects also
// using them.
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#endif
Then it proceeds to put that label before every function declaration.
PRINTF_VISIBILITY
int sprintf_(char* s, const char* format, ...) ATTR_PRINTF(2, 3);
PRINTF_VISIBILITY
int vsprintf_(char* s, const char* format, va_list arg) ATTR_VPRINTF(2);
I know that "link against" means doing something like
gcc -o main.o -c main.c
gcc -o printf.o -c printf.c
gcc main.o printf.o -o output
But what does the other option "include file directly" mean? What would be the gcc commands in this case?
Also, if there are other objects (which I think it means object files) using the functions, why make them static in the first place and how could they clash? How could, for example, main.c
use these functions if they are static?
Solution
But what does the other option "include file directly" mean?
I take that to mean source inclusion, via an #include
directive.
What would be the gcc commands in this case?
It would normally be a matter of source code, not GCC options, but GCC does have an -include
option that could be used for the purpose.
Also, if there are other objects (which I think it means object files)
Yes, other object files, though from a C language perspective the key concept is other translation units.
using the functions, why make them static in the first place and how could they clash?
If you have two different translation units contributing to the same program, and they both provide definitions of the same function, and more than one of those definitions has external linkage, then you have a collision between conflicting external function definitions. (The colliding definitions being lexically identical is irrelevant.) Declaring the functions with the static
keyword gives them internal linkage instead of external. Each such definition can be referenced by other functions in the same translation unit, but not by functions from other translation units. Internal function definitions from different translation units do not clash.
How could, for example,
main.c
use these functions if they are static?
main.c
having #include
d static definitions of these functions, any function in the translation unit can call the included functions normally. Nothing special is required, other than the inclusion of the function sources (which is a bit weird). The usual requirements for having in-scope declarations apply, of course, but typically that would be taken care of simply by performing the inclusion near the top of the source file.
As for the PRINTF_VISIBILITY
macro, the idea is that if you were using #include "printf.c"
, then you might want to first #define PRINTF_VISIBILITY static
so that you get static function definitions. If that macro is not otherwise defined, then the file defines it to expand to nothing, so that you get external definitions.
Answered By - John Bollinger Answer Checked By - Marilyn (WPSolving Volunteer)