Consider my small example C library:
#include <external_library.h>
void some_function(void)
{
external_library_call();
// Do other stuff...
}
It plans to make some_function() publicly callable. The library doesn't work, though, because the external library it requires also happens to use a function called some_function(), which happens to have the same prototype. GCC's linker doesn't care how many sources of the some_function symbol there are, though. It picks one seemingly at random and the external library may or may not use my some_function() instead of its own. This is insane. Not the fact that the library doesn't work. This library definitely shouldn't work. It's more the fact that there are two sources for the symbol 'some_function', but the linker doesn't do anything about it. And you know, that doesn't bother me too much because I'm used to GCC and C in general being pathologically reckless by default. There's gotta be a way, though, to get the linker to warn me when there are two sources for the same symbol. I've already tried -Wall -Wextra -Wshadow, but that doesn't produce any warnings.
Note that -fvisibility=hidden won't help here because both libraries want to export some_function(). I know you can just say shame on me for making function calls without a unique prefix. You're right. It's a mistake. I don't care. This mistake is catchable by the linker and so should be caught. There is no reason why the linker shouldn't catch this mistake. Besides, the library you're using might export some weird unexpected symbols, and you do not necessarily have control over what somebody else's library exports. That and prefixes can only be made so unique before the programmer halts and catches fire.
Add:
-fvisibility=hidden
To your build flags. Note some caveats, however; some headers might not be expecting this. In those cases, you need to use a pragma before including them:
#pragma GCC visibility push(hidden)
#include <problematic_header>
#pragma GCC visibility pop
There are some other benefits to this other than just avoiding symbol collisions. See:
http://gcc.gnu.org/wiki/Visibility
In case you're interested.
Options such as -Wall -Wextra -Wshadow
are compiler flags that affect the analysis of the source code; apparently, you're after a linker option.
However, since shutdown()
is in the namespace reserved for the application to use (and you don't even show that you've included the header that does declare the system shutdown()
), there is nothing much the compiler or linker can do. You as the application programmer are entitled to create a function called shutdown()
and call it. You could look at something like the LSB (Linux Standards Base) compliance suite to check that you aren't defining functions that are defined by the implementation.
One of the harder bugs I ever had to track down involved a function _bind()
in our code that happened to be the same name as a system function _bind()
that had a different interface. When our function was called by parts of the system library, all hell broke loose. That was partly our fault for using a name reserved to the system (don't start variable or function names with _
), it was unfortunate that only one platform had the name collision. A systematic prefix to our _bind()
resolved the issue.
You could look at the lists of reserved names in the C and POSIX standards. However, you'd find that the _t
suffix is reserved, but type names with the suffix are widely (ab)used for user-defined types too. You also have to know whether any given definition of the type is 'from a system header' (presumably OK), or from a user-defined header (probably not OK), or is a 'user-defined header providing missing system functionality' (border-line). It gets very tricky.