How can someone ensure whether source code of some c library (.a) uses global variables or not? Is there any tool which can parse such details?
A library consist of modules (compiled C files). A module can declare a global variable. Any module (inside or outside the library) referencing the global variable will cause the module that declares the global variable to be included in your build.
A global variable can be static. It is then only visible in that module.
A global variable can be extern. That means it does not exist in the current module, and could not exist in the library at all in which case the user must provide the variable.
In the first and the third case, the variable will be listed in the symbol table of the library or in the fixup table of the library. The first is the list of symbols available to a callee; the second a list of variables whose exact address must still be fixed at load time. There may be variables that must be fixed-up that are not exported. Symbols always include the name, fix-ups don't need to be listed with their name.
So a tool to look at the symbol table of the library is probably what can answer your question.
Note: the fact that a global variable is listed in the symbol table of the library does not imply the variable is used by any function in the library.
By hand:
In case you've already known how to open a .a file, take a look in it.
If in the file, there is:
A variable is used without declaration (so it is defined in another file)
A variable is declared out of every function
So this file contains global variable.
By tool:
Every compiler have this option for you (I believe)
For example:
With GCC, using GDB, type info variables to list all the global variable.
With VS, open Class View, find Global Functions and Variable
Related
my first question here.
can anyone explain to me the differnce between a global static variable (that is, defined above the functions and the "main" combined with "static") and a static variable that is defined inside a function?
as i understand it, they do the same - both enlarge the variable scope to the whole file, and both restrict it to the specific file. so... what am i missing?
plus another question (that came up when looking for a solution) - what is extern? i thought that defining a variable above the main would make it global (as in to other files too), but then i read someone explaining that in order to do so, i must add "extern" before the varible defining.
For variables defined outside of a function, the static keyword limits the variable to being referenced using its identifier from the file in which it is defined. Variables of this type will be assigned a fixed address by the linker (outside of the heap and stack), but will not be assigned a global symbol. If variables of this type are defined in multiple files with the same identifier, the linker should allocate separate memory in each case and should compile without warnings.
Variables defined with the static keyword inside of a function have similar memory allocation, but references to the variable using its identifier are limited to within that function. You could have multiple functions defining static variables with the same identifier and each will be allocated separately.
If an initializer is used for static variables, the variable is initialized once before the program begins executed and the initializer is evaluated at compile time. The initializer must evaluate to a constant expression in this case (no function calls or parameter or variable references).
The compiler will typically build each C file independent of all of the others in a program using symbols to define external dependencies, such as variables and functions located in other files. After each source file is compiled, the linker processes the compiler output to replace symbols with fixed addresses and build the entire program. In order to properly execute the build, the compiler must know the types and sizes of all external functions and variables. The type and number of parameters and return type of functions are typically shared in a header file using function prototype declarations. Function prototype declarations are implicitly identified as external by the compiler. The extern keyword is used to specify the type and size of variables declared in files outside of the file referencing the variable. Declaring a variable without the external keyword would cause it to be defined within the module where it is declared. If two variables with the same identifier are declared in multiple files without the static keyword, then the compiler will typically generate an error since the same global symbol is used multiple times in the program.
I have two tools in C to parse data from a database to an XML file or a normal text file. Both files contain the same function names but with different implementations, so I am working on merging them both in a single tool and the output type (XML or text) will depend on the input from the user.
So, the problem is having same function (and struct) names but with different implementations. How can I overcome this situation without having to rename everything because that will lead to a mess.
Thank you.
If you have to use both sets of types and functions in the same program at the same time, and if those type and function names have to be visible outside of their enclosing source file(s)1 (i.e., you have a .h file with those type definitions and function declarations), then you must rename at least one set of them. No other choice. C doesn't provide user-definable namespaces2, so anything with external linkage must have a globally unique name.
If those type and function names don't have to be visible outside of their source file3 (i.e., they don't have to be called by a function defined outside of their source file), then you can declare the functions as static - that will limit their visibility to the enclosing source file. If the type names are local to the source file (you haven't put them in a .h that must be included by another source file), then they won't be exported.
If you only need to use one set or the other, but which set isn't known until runtime, you can put each in a shared library and then load the correct one at runtime (using dlopen on the *nix side - not sure what the Windows equivalent would be).
A fourth option would be to switch to C++ and wrap each set in a unique namespace; depending on what you're doing that may be the fastest option.
The function names have what is known as external linkage.
C has four namespaces - label names, tag names, struct and union member names, and all other identifiers (variable names, function names, typedef names, enumeration constants, etc.). Those namespaces are fixed, and you can't create any more.
The function names have either internal or no linkage.
You can enclose each of the function definitions in a different namespace. You won't have to change intra-namespace function calls, but you will have to preface inter-namespace function calls with the "other" namespace.
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 understand that a static function in C allows that particular function to only be call within the confines of that file. What I am interested in is how this occurs. Is it being placed into a specific part of memory or is the compiler applying a specific operation to that function. Can this same process be applied to a function call in assembly?
Declaring a function static doesn't really prevent it from being called from other translation units.
What static does is it prevents the function from being referred (linked) from other translation units by name. That will eliminate the possibility of direct calls to that function, i.e calls "by name". To achieve that, the compiler simply excludes the function name from the table of external names exported from the translation unit. Other than that, there's absolutely nothing special about static functions.
You still can call that function from other translation units by other means. For example, if you somehow obtained a pointer to static function in other translation unit, you can call it through that pointer.
It doesn't make it into the object's name table which prevents it from being linked into other stuff.
Functions and other names are exported as symbols in the object file. The linker uses these symbols to resolve all sorts of dangling references at link time (e.g. a call to a function defined in another file). When you declare it static, simply it won't be exported as a symbol. Therefore it won't be picked up by any other file. You could still call it from another file if you had a function pointer to it.
It's in fact the opposite. When a function is not static, its name is written somewhere in the object file, which the linker can then use to link other object files using this function, to the address of that function.
When the function is declared static, the compiler simply doesn't put the name there.
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