This question already has answers here:
How are static variables with the same name in different functions identified by the System?
(3 answers)
Closed 8 years ago.
I have tried running and compiling the code where I have defined the static variables with the same name in two different source files. The code was compiled successfully and running.
Now my question is that both the static variables reside in the .data/BSS section in the memory. As per my understanding two different memory locations must have a separate unique name identifier. Why this was not a problem in this case?
"As per my understanding two different memory locations must have a separate unique name identifier." - it is not clear what you mean by "memory locations" in this case. Memory locations have addresses, not names. If by "memory locations" you mean "individual variables", then the above statement only applies to variables with external linkage. Variables with external linkage need externally visible names. Variables with internal linkage (static variables) don't.
In a typical implementation all static symbols are resolved internally by the compiler, at the compilation stage. They do not produce external names in object files. I.e they are not exposed to the linker at all. In the simplest case all static variables from the same translation unit are are seen by the linker as a single blob of data.
By the time different translation units are brought together for linking, all names of static variables are no longer necessary. By that time they are long forgotten. Which is why naming conflicts do not have a chance to occur.
P.S. In C++ language inline functions with external linkage are allowed to define static variables inside. To provide proper functionality, compilers typically assign external names to such static variables. C language, which also supports inline functions, decided to deal with this matter differently: in C language inline function definitions are simply prohibited to contain static variable definitions.
Related
I am a little confused on the purpose of static functions in C, if anybody can explain that would be great! :)
I understand that static functions are used to limit the function’s visibility but why is it used?
Large programs are built with multiples subcomponents, which may be in separate groups of source files within one company or in libraries provided by third-party vendors.
When a function is not declared with static, its identifier has external linkage. This means any two instances of the identifier will be linked to refer to the same function.
Sometimes we do not want that. One person writing something for one part of the program might have called one function they use CalculateSquare because it calculates the square of a complex number, and another person writing something for another part of the program might have called a function CalculateSquare because it calculates some properties for a geometric square. If both of these identifiers have external linkage, this will generally result in a link error due to multiple definitions or, worse, linking in one definition and not the other with no error message (which can happen when one is in a library file).
When a function is declared with static, its identifier has internal linkage. This means uses of its identifier inside the same translation unit, after its declaration, will refer to that function, but uses of the same identifier in other translation units will not refer to the function in this translation unit. This allows programmers to pick their names more freely, without worrying about collisions with names other programmers use.
(There are other ways to avoid multiple definition errors. Linkers often have commands to control the publication and use of symbols in their output files, and those sometimes have to be used and may provide features that merely using static does not. However, using static is a standard and easy way to handle this in many situations.)
This question already has answers here:
C: Why do we include header files, which declare but don't define?
(5 answers)
Closed 4 years ago.
This is the question I still cannot answer by myself (probably due to lack of experience in C).
So I found this answer and the question is what's wrong with putting definitions into a header files? I we don't declare them as static it should be fine since they will have external linkage and linker will not complain.
Secondly, why should not we put static definition into a header file? Suppose we want to make some function sort of "compilation-unit private" that is not intended to have external linkage.
And what I was surprised about was why is it (rarely) possible to put inline function definition into header files?
Is it just by convention only?
There is not usually any point in putting information into a header unless it will be included in multiple other source files. That means that if the header defines some variables, each source file that includes the header will define those variables. And it is normally an error to define the same (global) variable more than once. So, putting variable definitions into a header normally defeats the reason for creating a header in the first place.
Note that C does have a 'one definition rule', similar to C++, but not as strong. There is a 'common' extension — complete with double entendre — that often allows you to get away with defining a variable in more than one file, but it doesn't work if the variable has a non-trivial initialization.
You can find a lot of information in How do I use extern to share variables between source files?, including information about the common extension.
You should not normally define static variables in a header because that means that each file that includes the header will define its own copy of the variables. This is usually not what's wanted. It tends to make programs bigger.
If you reliably work with compilers that support inline, there is no particular reason why you can't put static inline function definitions into a header. There is a risk that if the function cannot be inlined, then the compiler will generate a static function in the object code for each source file that uses the function, again increasing the size of the executable. You might be able to avoid that by using non-static inline function definitions. If the functions are small enough that they will be inlined, there is no particular reason not to put them in a header.
You can find more information about inline functions, with static or extern, in the Q&A on Stack Overflow:
extern inline
Is inline without static or extern ever useful in C99
What's the difference between static and static inline functions?
Note the rather extensive use of weasel words such as 'usually' and 'normally' in the answer above. You can, with care, find exceptional situations that warrant breaking the rules, but if you remember that headers are the glue that provide cross-checking between the code that uses some functionality (types, constants, functions, sometimes variables) and the code that implements the functionality, then you'll realize that it is good to follow these rules:
Headers declare types, constants, enumerations, functions, variables that are used by multiple source files.
Source files implement functions and define variables that are used by multiple source files.
The header files are used by the implementation code to ensure that the implementation matches the specification.
The header files are used by the consumer code to follow the source-level rules for the implementation.
Header files should not define variables.
Source files should not declare external variables; they should include the relevant header.
Headers may sensibly define static inline functions; you may even include plain inline function definitions in a header, but you have to be careful to instantiate the functions somewhere in case they are not inlined — and that's when extern inline comes into play. (Be aware that old GCC rules for inline functions are different from C99 standard rules.)
There are some rules that simply including a header won't enforce, such as required sequences for calling functions (don't call a free function before the corresponding allocate function, for example). But using headers wisely prevents a lot of errors.
See also:
Should I use #include in headers?
How to link multiple implementation files in C?
And many other questions, no doubt.
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
I tried different websites but I don't get it. Could you explain it in simple english?
"scope" is a namespace of the compiler;
"linkage" is about compiled units.
I explain a bit more: A variable declared in a function has the scope of that function, i.e. it is visible only within that function. A variable declared as static in a source file, can be seen only by the code in that source file (and all included files!). Variables can also have global scope: they can be referred to in a source file, but not declared (allocated) in that source file but declared in another source file.
In stead of "source file" we should say "compilation unit" as it is the C source file being compiled, plus all included files. Scope refers to everything the compiler can "see" in a compilation unit. These are namespaces.
After compilation of a project there are a number of object files, one for each compile unit. Each may refer to variables used that are not declared in the compile unit. The linker must now resolve these references between object files: linkage.
This also holds for functions.
Keep reading on your page (http://msdn.microsoft.com/en-us/library/teta4z44.aspx). This is talking about visibility of objects between translation units (source files). It first talks about "internal linkage": objects defined as static, unique to the translation unit but available throughout.
Next it talks about "external linkage": a like-level object not declared static. These are shared between translation units.
Finally, "no linkage": an object such as a variable within a function, not declared extern, which is unique to that scope.
If you follow the links on the bottom of the page, it's all explained.
Share what I learned about this issue.
Scope is for the benefit of the compiler, while linkage is for the benefit of the linker.
The compiler uses the scope of an identifier to determine whether or not it's legal to refer to the identifier at a given point in a file. When the compiler translate a source file into object code, it notes which names have external linkage, eventually storing these names in a table inside the object file.
Thus, the linker has access to names with external linkage; names with internal linkage or no linkage are invisible to linker.
(The above text is from book "C programming: A modern approach", which contains an exactly same question).
I can imagine static variables var inside a function func to be named like var#func,
what about global static and non-static variables?
Compilers don't need to uniquely name things with internal linkage, like static variables and functions. You can't access static objects outside the translation unit, so the linker doesn't need to get a name for them.
Global variables with external linkage don't usually have much mangling or decoration applied to their names, and it's often exactly the same that is applied to functions. A single leading underscore is not terribly uncommon.
Adding on that since the information given here is at least incomplete. Most compilers will create "local" symbol for static variables, and yes, since the naming of static variables in function scope is not unique, they have to mangle the names. gcc, e.g, does that by appending a dot and a unique number to the name. Since the dot is not part of any valid identifier, this makes sure that there is no name clash.
Things become obscure when the compiler supports universal characters in identifiers. Depending on the environment, the compiler has to mangle such identifiers, since e.g the loader might not support such characters in the symbol table.
icc chooses something like replacing such a character by _uXXXX where XXXX is the hex representation of the character. In that case (icc) this results in two subtle compiler bugs. First, this mangling uses valid identifiers that the user is allowed to use, so they may clash for global symbols with identifiers from the same compilation unit or even from other units. Second, icc even mixes up its own internal naming and reserves only space for one static variable and if they are eg also declared volatile completely runs into the wild.