Why won't C compile if two separate source files in the same workspace share function names? - c

I'm using eclipse indigo, gcc and cdt in a project. If two functions in separate source files share names (regardless of return type or parameters), eclipse flags a redefinition error. This isn't a huge issue regarding this project given I can easily rename these functions, and I'm well aware of wrappers if it were. Although this isn't a critical issue, it does make me think I'm not understanding the c build process. What occurs during the build process in which a program structure like this would cause issue?
Here's some more info. on the situation, and where my understanding is so far -- not necessary to answer the question, although there must be a hole in my understanding.
In this case, the two functions are intended to be used only locally, as such their prototypes are not given in the .h interface, and for the sake of my point, neither are defined 'static'.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units. With that in consideration, I would have assumed that the neither source file is aware of the presence of the other, and the compiler would have no problem indexing the two functions, as the separate files would allow for proper distinguishing between the two during linking -- so long as they weren't included in the same compilation unit.
I noticed that statically defining either instance of the function declaration removes the error. I remember reading at some point that every function not declared static is global -- although given these functions are not a part of the .h interface, the practical example in which including the .h interface doesn't allow for the including program to reference all .c functions would indicate "hiding" these functions would be of no issue.
What am I overlooking?
Some insight would be greatly appreciated, thanks!

This is the concept of "linkage". Every function and variable in C has a linkage type, one of "external", "internal", and "none". (Only variables can have no linkage.)
Functions have external linkage by default, which means that they can be called by name from any compilation unit (where "compilation unit" roughly means one source file and all the headers it includes). This can be expressed explicitly by declaring them extern, or it can be overridden by declaring them static. Functions declared static have internal linkage, meaning they can be referenced by name only from other functions in the same compilation unit.
No two external functions anywhere in the same program can have the same name, regardless of header files, but static functions in different compilation units may have the same name. A static function may have the same name as an external function, too -- then the name resolves to the static function within its compilation unit, and to the external function elsewhere. These restrictions make sense, for otherwise it would be possible for a function call to be ambiguous.
Header files don't factor into the linkage equation at all. They are primarily a vehicle for sharing declarations, but a function's linkage depends only on how it is declared, not on where.
I leave discussion of variables' linkage for another time.

It doesn't matter whether one source module includes headers for another. Header files only contain declarations for the purpose of local functions being able to find functions in other modules. It doesn't mean that functions not declared don't exist from the perspective of that module.
When everything gets linked together, anything not specifically defined to be local to one source module (i.e. static) has to have a unique name across all linked components.

remember reading at some point that every function not declared static is global
Having understood this you got the main point and reason for the behaviour observed.
.h files are not known to the linker, after pre-processing there are only translation units left (typically a .c file with all includes merged in), from which .o files are compiled.
There are no interfaces on language level in C.
Neither of these source files are being included anywhere in the project, so they shouldn't be sharing any compilation units.
Declare those functions as static. This is the only way to "hide" a function from the linker "inside" a translation unit.

C doesn't "mangle" function names the way C++ or Java do (since C doesn't support function polymorphism).
For example, in C++, the functions
void foo( void );
void foo( int x );
void foo( int x, double y );
have their names "mangled" into the unique symbols1
_Z3fooid
_Z3fooi
_Z3foov
which is how overloaded function/method calls are disambiguated at the machine level.
C doesn't do that; instead, the linker sees two different function definitions using the same symbol and yaks because it has no way to disambiguate the two.
1. This is what happens on my system, anyway

Related

What is and isn't available to linked files in C?

As of late, I've been trying to work through opaque pointers as a programming concept and one of the main things I've had difficulties with is figuring out what is or isn't available to other files. In a previous question, I failed in trying to create an opaque pointer to a struct and even though the answer explained how to fix that, I still don't quite understand where I went wrong.
I think that if a struct is defined in file2.c, file1.c can use it if both files include header.h which includes a declaration of the struct? That doesn't entirely make sense to me. header.h is used by both files, so I can see how they would access the stuff in it, but I don't understand how they would use it to access each other.
When I started programming, I thought it was pretty straight forwards, where you have program files, they can't access anything in each other, and those program files can #include header files with definitions and declarations in them (e.g. file1.c has access to variables/functions/etc. defined in header.h). Turns out I was wrong and things are quite a bit more complicated.
So from what I can tell, func() defined in header.h can be used by file1.c without being declared in file1.c, if file1.c includes header.h. As opposed to var defined in header.h which needs to be declared in file1.c with the extern keyword? And I think if var is defined in file2.c, file1.c can use it if it extern declares it, even if neither file1.c nor file2.c include header.h?
I apologize if the previous paragraphs makes no sense, I'm having quite a bit of difficulty with trying to describe something that confuses me. By all means, please edit this if you are able to fix mistakes or whatnot.
Books and webpages don't seem to help at all. They end up giving me misconceptions because I already don't understand something and draw the wrong conclusions, or they bring up concepts that throw me off even more.
What I'm looking what I'm looking for is an answer that lays this all down in front of me. For example 'this can access this under these circumstances', 'this cannot access this'.
Functions defined in one .c file can use anything defined in another .c file except for those things which are marked as static. Functions and global variables which are marked as static cannot be accessed from other translation units.
Whether something is declared in a header file or not doesn't really matter--you can declare functions locally in the same .c file which calls them if you want.
Your question asks about “access” at several points, but I do not think that is what you mean to use. Any object or function can be accessed (for an object: read or written, for a function: called) from anywhere as long as a pointer to it is provided in some way). I think what you mean to ask is what names are available.
Any declaration that is outside of a function is an external declaration. In this use of “external” in the C standard, it simply means outside of a function. (That includes a function declaration or definition; although it is declaring or defining a function, it is not inside itself or any other function declaration, so it is outside of any function.)
Any identifier for an object or function with an external declaration has either internal linkage or external linkage. If it is first declared with static, it has internal linkage (and may be later declared with extern, but that will not change the linkage). Otherwise, it has external linkage.
Any identifier with external linkage will refer to the same object or function in all translation units (provided other rules of the C standard are satisfied—a program can do various things that will result in behavior not defined by the C standard).
Thus your answer is: The name of any object or function that is (a) defined outside of any function and (b) not initially declared with static is available to be linked to from other translation units.
Some technicalities that may be of interested:
What people think of as a variable is two things: an identifier (the name) and an object (a region of memory that stores the value).
Identifiers have scope, which is where they are visible in the source code. Identifiers declared outside functions have file scope; they are visible for the rest of the translation unit. Identifiers declared inside functions have various other types of scope: function scope, function prototype scope, and block scope.
You may sometimes seem people refer to global scope or external scope, but these are misnomers; they are not terms used in the C standard.
Linkage is related to scope and is sometimes confused with it, but linkage is a different concept: Two identical identifiers declared in different places can be made to refer to the same thing. Those identifiers have different scopes, notably one having file scope in one translation unit and the other having file scope in a different translation unit. Since each translation unit is compiled separately, the compiler generates code regarding each identifier separately. When the object modules are linked, then the code is bounded together, causing the separate identifiers to refer to the same object or function.
Identifiers can be declared with extern inside functions, but these can only link to objects or functions defined elsewhere; external definitions cannot appear inside functions.

Why is a function defined in a .h file redefined in a .c file?

I am reading through Linux v3.19's implementation of PID namespaces and in pid_namespace.h there are functions defined that are redefined in pid_namespace.c. For example, in pid_namespace.h there is the following definition:
static inline struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *ns)
{
if (flags & CLONE_NEWPID)
ns = ERR_PTR(-EINVAL);
return ns;
}
And then in pid_namespace.c there is a second copy_pid_ns definition:
struct pid_namespace *copy_pid_ns(unsigned long flags,
struct user_namespace *user_ns, struct pid_namespace *old_ns)
{
if (!(flags & CLONE_NEWPID))
return get_pid_ns(old_ns);
if (task_active_pid_ns(current) != old_ns)
return ERR_PTR(-EINVAL);
return create_pid_namespace(user_ns, old_ns);
}
What does this re-defining achieve? Why is it done? Thanks for your help!
These two definitions corresponds to two incompatible configurations:
Definition of copy_pid_ns in the include/linux/pid_namespace.h#L76 header is parsed only with CONFIG_PID_NS option disabled (see line 68 in that header).
The file kernel/pid_namespace.c is compiled only with CONFIG_PID_NS option enabled (it can be found from kernel/Makefile). For that configuration the header contains just a declaration of the function at line 62.
Situation when the header file declares some function twice is quite natural for the Linux kernel sources:
One declaration (without definition) corresponds to some functionality being enabled. In that configuration the function is defined in some source file which is compiled only with functionality being enabled.
Another declaration is a definition of static inline function and corresponds to disabled functionality.
Note
The question omits relevant information from the source code repository it extracted the source code from, so the answer below does not apply to the source code in those files. It appears at most one of the two definitions is selected based on build options, so they are not both used in the same build.
Old Answer Regarding static inline
The version in the header is marked static inline. In this declaration, static causes the name copy_pid_ns to have internal linkage, meaning the definition here will apply only to uses of copy_pid_ns in the current translation unit (the source file being compiled, including the files it includes). The idea of inline is that this function is so small, it would be good if, wherever it is called, the compiler just wrote the code for it in place of the call instead of actually using a subroutine call instruction for the function. (Technically inline is just a suggestion to the compiler in this regard. Good modern compilers mostly make their own decisions about which functions to inline.)
Because the definition in the header is static inline, it is not accessible to other translation units. The definition in the other source file has external linkage, meaning any uses of copy_pid_ns in other translation units can be linked to it (if they do not have their own private static version). Those uses in other translation units will have to use actual subroutine call instructions to call this function.
Providing an external version is not necessary if all uses of copy_pid_ns have the static version available, but one may be provided because that is not always the case or just as a safety fallback.
First look at qualifiers in front of the function:
static inline... -> static will be resolved only in included source files (*.c, *.cpp)
like private qualifier, inline will replace directly this function instead accessing it as reference
have no qualifiers -> more like a public external function. If you define your usage of the function as extern you should compile (*.c) file which contains implementation of the function and then the linker will resolve your call to the function as reference.
It's not a redefinition. The key to realizing what's intended here is the presence of static qualifier for the first definition, and knowing how programs are built with C. Also, inline is seldom used without static, at least with C89 and GNU extensions which is what is used to compile Linux, but inline in and out of itself doesn't play a role here.
The static inline definition in pid_namespace.h is only visible to the translation unit (.c file) that includes that header file, directly or indirectly. The static qualifier is what restricts this visibility. If you include pid_namespace.h from another translation unit, that translation unit will have its own, another copy of the function. Each object file will have its own copy of the function definition, available only to itself. Additionally, because of the inline qualifier, the function may not even exist as such because the compiler is free to "inline" it.
The second definition does not have a static qualifier and can thus be used by other translation units that do not themselves contain it. The C compiler compiles object files from their respective translation units, and the linker links these object files together and produces a program image where references to said definition are correctly resolved. The compiler does not care if more than one translation unit embed the same function -- to it they're just object files it needs to compile one by one. But the linker will abort because it isn't designed to have to choose between such multiple definitions in its input.
In practice, there is many ways this can be used. The former definition may be the short version used in kernel mode (privileged kernel code), while the latter is used in user mode, as result of processing a system call, for example.
In general, defining procedures several times is permitted as long as there is at most one object available to the linker (in case it needs to resolve references to the function, like function calls). You can juggle your .c and .h files however you like, as long as that requirement holds. If you also know how to use static and inline qualifiers, you can add definitions that are not externally visible (static) and benefit from compiler being able to inline them.

Why should I declare a "private" function static when I can simply not put it in the header file?

I understand the static keyword is used for creating functions or variables which are "private" to the translation unit (the source file).
However, as far as I understand, in order to make sure a particular function or variable is not accessible from outside the .c file that it was declared in, I can simply not declare it in the corresponding .h file.
For example:
f.c
void public_func() {
// ...
}
void private_func() {
// ...
}
f.h
void public_func();
// no declaration of private_func
So why should I also declare private_func as static? Is that simply a convention or does it have a technical benefit over simply not declaring it in the .h file?
The problem is that compilers work on "translation unit" basis, meaning one .c file and all the .h files it includes. So it is traditionally not able to detect naming collisions across the whole project.
So if you don't make it static, the function has "external linkage" per default. Meaning if have a function private_func and another translation unit in the same project is using the same name, you get namespace collisions during linking and linker errors.
It is also a matter of correctness - private functions/variables should simply not be accessible from the outside, neither intentionally nor accidentally.
I understand the static keyword is used for creating functions or variables which are "private" to the translation unit (the source file).
That's true.
Is that simply a convention or does it have a technical benefit over simply not declaring it in the .h file?
There is a technical point here. Once compiler is done doing it's job it produces an object file. That file has a symbol table, which is later used by linker when the linker puts a program together from separate object files. static functions will not get into that table, so that direct references to that function from other object files will fail with "unresolved reference" error in the linking stage.
Benefits? Well you save some tiny space in you object file, linking stage will go faster, since there will be a smaller table to process. But that's tiny enough to not make a difference, unless we're talking about a made up case of thousands of functions with loooong names.
If you have a non-static function and you omit it's declaration in the header file, the function name still gets into a symbol table. And if I happen to know the declaration somehow (other than from the header) I can still call/reference the function directly from another translation unit, no linker error will happen.
Let's say you write a library that consists of several .c and .h files. The clients of your library will need to use some of the header files to use your library. They should only see the public functions.
But for the implementaiton of your library, you might also use header files so functions in your library can call other (internal) functions.
So you end up with two types of declarations:
For clients of your library
void public_func();
For internal use
static void private_func();
Preferrably, the private and public declarations are in separate header files and the clients of your library only need to include the header files with public functions.

Why does the same named private function inside two .C files cause a multiple definition error?

I am coding in the Cypress PSoC IDE (C99 ARM_GCC). When I use an identically named function in two *.c modules (for example void MyClear()) I get the error:
Build error: multiple definition of `Clear'
MyClear() is not mentioned in any header, and I presumed that it is private to the .C file but I'm obviously wrong.
Point 1:
In C, functions are global by default.
There is no concept of private in C. FWIW, there is static, however, which limits the scope of the function to the translation unit only . See this previous question and the answers for some clarifiction.
Point 2
You get this error in linking state. When all the translation units have been compiled and about to be linked together, linker can see more than one definition of the function and hence throws the error.
Point to note: You don't define functions in header files. you declare them, and as long as declarations don't conflict, you can have any number of declarations even inside a single translation unit.
Functions are public (meaning their name gets exposed to the linker) if not defined with static.
functions can't be private in C. try defining it with static
You are linking both the files to create one executable binary isn't? And hence there cannot be a duplicate definition of a function.
Compiler will resolve the function names (symbols) to unique addresses in the executable binary. If it sees two definitions, it has a dilemma which one to choose for when the function is called during run, the execution can jump to one location and that needs to be pre-determined. As such compilers aren't happy with multiple definitions.
To get over you could use static with that function.
And here is the best answer to what is static in c.

How to deal with duplicated function name within C?

I have a little project in which I named two same name function in two different source file, but while I building the project, the compiler failed with 'func_name already defined in filename.obj'.
Why could not I have two functions with the same name in two different source files? I thought the function should be local to the source file only if when we declared it in the header file will it become global.
And except for changing the filename, are there any other elegant solution to duplicated function name in the C programming language?
In C, a function has global scope by default. To restrict its scope, use the static keyword to make it private to a the module.
The role of the header file is just to publicize the function along with its signature to other modules.
All global names must (with some caveats) be unique. This makes sense because that name is what is used by the linker to connect a function call to implementation of the function itself.
Names with static and local scope need only be unique within their scope.
Whether some thing is declared in header file or in source file makes absolutely no difference for the compiler. In fact, the compiler proper knows absolutely nothing about any "header files", since header files are embedded into source files by so called preprocessor, which does its work before the compiler proper. By the time the source files (with embedded header files) get to the actual compiler, there's no way to tell what was there originally and what was inserted from header files. The source file with all the header files embedded into it is called translation unit. I.e. the compiler proper works with translation units, not with some "source" or "header" files.
In C language all objects and functions declared at file scope have external linkage by default, which means that they are global, unique for the entire program. So, you thought incorrectly. Functions are not local to one source file only.
If you want to make a function (or an object) local to a single translation unit, you have to take some explicit steps. You have to declare it as static. Declaring it as static will give it internal linkage, which essentially means that it becomes internal to its translation unit.
Declaring your functions static will only work if both of them really have to be local to their own translation units. If this is not the case, i.e. if at least one of the functions should be a globally accessible (linkable) function, then you have no other choice but to rename one of functions.
Why could not I have two function with the same name in two differenct source file?
Because the linker needs to know which is meant when you reference it.
Imagine that a.h and b.h both declare my_function(). The compiler generates code for both. Now, imagine that c.c calls my_function() - how does the linker know which of the two versions of the function should be called?
Declare the function static to make it local to the file. In C, every identifier name must be unique.
The elegant solution is namespaces introduced in C++. The solution, if there are few calls to func_name is take one, rename it and recompile.
Something hackerous but quick solution might be this:
//In one of the two source files and any file that calls it
//if your functions is something like this
//void func_name(int) { ... }
//Add the following line
#define func_name SOME_UNIQUE_FUNC_NAME

Resources