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
Related
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.
Do I need to declare all functions I use in a .c file in a header file, or can I just declare and define right there in the .c file? If so, does a definition in the .c file in this case count as the declaration also?
Do I need to declare all functions I use in a .c file in a header file,
or can I just declare and define right there in the .c file?
You used "use" in the first question and "define" in the next question. There is a difference.
void foo()
{
bar(10);
}
Here, foo is defined and bar is used. You should declare bar. If you don't declare bar, the compiler makes assumptions about its return type.
You can declare bar in the .c file or add the declaration in a .h file and #include the .h file in the .c file. Whether you use the first method or the second method is up to you. If you use the declaration in more than one .c file, it is better to put that in a .h file.
You can define foo without a declaration.
If so, does a definition in the .c file in this case count as the declaration also?
Every function definition counts as a declaration too.
For the compiler, it does not matter if a declaration occurs in a .h or a .c file, because the compiler sees the preprocessed form.
For the human developer reading and contributing to your code, it is much better (to avoid copy&pasting the same declaration twice) to put the declaration of any function used in more than one translation unit (i.e. .c file) in some #include-d header.
And you can define a function before using it.
BTW, you might even avoid declaring a function that you are calling (it defaults to returning int for legacy purposes), but this is poor taste and obsolete way of coding (and most compilers can emit a warning in that case).
No, it is not necessary.
The reason of the header files is to separate the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the .c file defines "how" it will perform those features.
This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.
The answer to both questions is yes. You can declare c-functions in both header and .c file. Same with definition. However, if you are defining it in header file, you may have slight problems during compilation.
By default functions have external linkage. It means that it is supposed that functions potentially will be used in several compilation units.
However sometimes some auxiliary functions that form implementations of other functions are not designed to be used in numerous compilation units. Such functions declared with keyword static have internal linkage.
Usually they are declared and defined inside some .c module and are not visible in other compilation units.
One occasion that requires functions to be declared in a separate header is when one is creating a library for other developers to use. Some libraries are distributed as closed source and they are provided to you as a library file (*.dll / *.so ...) and a header.
The header file would contain declarations of all publicly accessible functions and definitions of all publicly required structures, enums and datatypes etc.
Without this header file the 3rd party library user would not know how to interface with the library file and thus would not be able to link against it.
But for small, trivial C programs that are not intended for use by other people, no you can just dump everything into a C file and build it. Although you might curse yourself years later when you need to maintain that code :)
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
Is there a case when a function can be defined within a header file? I was told by person whose opinion I respect that there are cases when a function can be defined in a header file included by multiple C source files. However, I could not find any. Just confirm, I define the function in-line in a header file but that also did not work. I will but have not found any answers yet. There is no practical requirement as such. I just wanted to see if there is some part of the C standard that I don't know of which will allow this. Thanks for any answers
Yes, but only if it is declared as static inline.
Functions that are declared simply as inline behave exactly like functions that are defined with no modifiers, except that they may be inlined within the translation unit that they're defined as inline in. They still have global scope, so including them in a header file will result in errors, as the function will be multiply defined.
static inline functions, on the other hand, do not have global scope — they only exist where they are used, more in line (ha ha) with the way you probably think of inline functions. As such, they're appropriate for use in header files.
No C function should not be defined in Header files.
function declaration can go in Header files.
But function definition should not ever go in header files.
Reason:
If function defination goes in header files then header will be included by multifple c files and when they are going to compile they will give error for multi defination of same files.
static inline function can be defined in Header files.
But that should not be used because
The "static" keyword in "static inline" is harmful in the situation
where a "static inline" function gets included and compiled in N
different files and does not get inlined. In this situation, one would
typically want the N copies of this function to get merged into one,
to avoid code bloat. But the "static" keyword prevents that, forcing
the linker to not merge these redundant functions.
As a side note to the answers/discussion on inline functions, I believe that theoretically one could define a function in a header in the same way as in a normal .c file, providing the header was only included once and in single location.
Though I'm not sure if the standard explicitly forbids this or not, it follows from the idea that the contents of a header file are essentially being copied and pasted into the top of the source file in which it is included from which point of view, there would be no issue.
I've read repeatedly that header files should include all the declarations that other files will need to use the source code. Suppose then that you have a function that is not used directly by other source files (a non-interface function, in other words). Should its prototype be placed at the top of the .c file, since it will not be used by other files? Or should it be placed in the header files with all the other functions, in order to fully summarize the functions present in the .c file in one place?
The header contains the interface information (whatever is needed for the outside world to use the functionality in the "module" -- e.g. the .c file). So internal functions (that are not used from outside), do not go into the header
In the .c file it depends on organization
some people like to list all internal function declaration at the top, so they are in one place.
others rely on ordering so a function is defined by the time it is used (in another function); and only forward declare it if necessary (e.g. recursive functions that call each other)
If the function is not used by other .c files, it should not have a prototype in a header file. You should give it the static modifiler, and place
the prototype at the top of the (only) .c file where it is used.
If it's reasonable and possible, you can just define the function before all the
functions that call it, so you don't even need a prototype.
Yes, the prototype of a private function should be placed in the same .c file as the function. The header defines the external interface.
Rather than forward declarations, some programmers prefer to define the functions in the order they're used so prototypes are unnecessary. Of course, you can't do this if two or more functions call each other.
My personal preference is to declare all of the functions first, so you'll have an overview of the file.
If you have functions that are used within a single module (a small set of files that together implement a functional unit), it's perfectly reasonable to create a second module-specific header file. All of the files in the module—but no external source files—will #include it.
Given that header files are essentially the only way to declare an external interface in C, things not part of that interface should not be in the header file.
C being what it is, sometimes this is not practical, because the internal view of an externally visible definition needs to refer to it; in this case you might place it in the header but protected by a #define that clearly indicates its internal provenance, and likewise use #ifdef to select the internal vs. external version of the definition that requires it. (You will see this in system header files often.) It's better to try to avoid this, though.
Putting at all the function declarations in the prototype syntax at the top of the .c source file is good style in my opinion. It serves also to document you source code for the reader.
You don't want to put the declarations in the .h header file as you would unnecessarily expose the internals of your programs.
Oh, and don't forget to add the static specifier in the function declarations.