I’m pretty new to C, and I know that static functions can only be used within the same object file.
Something that still confuses me though, is how if I hover over a call to printf in my IDE it tells me that printf is a static function, when I can perfectly use printf in multiple object files without any problems?
Why is that?
Edit: I’m using Visual Studio Code the library is stdio.h and compiling using GCC
#include <stdio.h>
int main()
{
printf("Hello, world!");
return 0;
}
Hovering over printf would give that hint
Edit 2: if static inline functions are different from inline functions how so? I don’t see how making a function inline would change the fact that it’s only accessible from the same translation unit
Edit 3: per request, here’s the definition of printf
in the stdio.h
header
__mingw_ovr
__attribute__((__format__ (gnu_printf, 1, 2))) __MINGW_ATTRIB_NONNULL(1)
int printf (const char *__format, ...)
{
int __retval;
__builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
__retval = __mingw_vfprintf( stdout, __format, __local_argv );
__builtin_va_end( __local_argv );
return __retval;
}
2
Answers
Thanks for all the updates. Your IDE is showing you implementation details of your C library that you’re not supposed to have to worry about. That is arguably a bug in your IDE but there’s nothing wrong with the C library.
You are correct to think that a function declared
static
is visible only within the translation unit where it is defined. And that is true whether or not the function is also markedinline
. However, this particularstatic inline
function is defined insidestdio.h
, so every translation unit that includesstdio.h
can see it. (There is a separate copy of the inline in each TU. This is technically a conformance violation since, as chux surmises, it means that&printf
in one translation unit will not compare equal to&printf
in another. However, this is very unlikely to cause problems for a program that isn’t an ISO C conformance tester.)As "Adrian Mole" surmised in the comments on the question, the purpose of this inline function is, more or less, to rewrite
into
(All the stuff with
__builtin_va_start
and__mingw_vfprintf
is because of limitations in how variadic functions work in C. The effect is the same as what I showed above, but the generated assembly language will not be nearly as tidy.)Update 2022-12-01: It’s worse than "the generated assembly language will not be nearly as tidy". I experimented with all of the x86 compilers supported by godbolt.org and none of them will inline a function that takes a variable number of arguments, even if you try to force it. Most silently ignore the force-inlining directive; GCC gets one bonus point for actually saying it refuses to do this:
In consequence, every program compiled against this version of MinGW libc, in which
printf
is called from more than one.c
file, will have multiple copies of the following glob of assembly embedded in its binary. This is bad just because of cache pollution; it would be better to have a single copy in the C library proper — which is exactly whatprintf
normally is.(Probably not exactly this assembly, this is what godbolt’s "x64 MSVC 19.latest" produces with optimization option
/O2
, godbolt doesn’t seem to have any MinGW compilers. But you get the idea.)__mingw_ovr
is normally defined asIt appears that this definition of
printf
is a violation of the C standard. The standard says