How does the compiler detect duplicate definition across translation units - compiler-theory

How does a compiler detect duplicate definition across translation unit. Suppose there were a extern const variable declaration in an header file. If this header file was used in more than one translation unit - each having a separate definition - each TU object creation would be successful, however when the final executable is created the error is thrown.
Is there a reference table created to account these duplication while linking each of these TU (during the creation of the executable)?
Any link on this topic would be helpful.
Thanks in advance for your explanation.

Normally this would be detected by the linker, rather than the compiler. The linker can then either coalesce the variables (often required for sloppy C/C++ coding) or report an error.

Yes, the linker builds a list of unresolved external references and then eventually goes on to attempt to resolve them one by one.

Related

Can the gnat compiler find unused specification procedures/functions/variables?

Is there a warning option switch that will identify spec-level procedures, functions, or variables that are not called or referenced anywhere? I've tried the switches below without luck.
This is what I'm currently using:
-gnatwfilmopuvz
-- m turn on warnings for variable assigned but not read
-- u turn on warnings for unused entity
-- v turn on warnings for unassigned variable
When I move unused variables from the spec to the body, the compiler correctly identifies them as not referenced. I would like to understand why the compiler won't identify unused code in the spec, and if there is a way to get it to do so. An excessive number of warnings isn't a concern, because I use the filter field in gnat studio to only look at a few files at a time, and I can easily filter to ignore library packages.
Any help is very appreciated.
The compiler will only detect unused items in the unit it is compiling.
If you have items in a package spec, you can know they are used (or not) only by exploring the whole project's Ada sources. Some tools like AdaControl can do it.
You need a tool for that: gnatelim. Its main use is to reduce the size of the executable, eliminating the object code for unused subprograms, but you can use its output just to get the list of unused subprograms. As far as I know, it will not detect unused variables in the spec, only procedures and functions.
https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gnat_ugn_unw/About-gnatelim.html
Use link-time garbage collection: https://docs.adacore.com/live/wave/gnat_ugn/html/gnat_ugn/gnat_ugn/gnat_and_program_execution.html#reducing-size-of-executables-with-unused-subprogram-data-elimination
You can then add the linker option --print-gc-sections to instruct the linker to print out a list of all symbols that were garbage collected.

Error Handling in LC-3?

I have this question on my review sheet that I cant seem to get but rather than ask you for the answer I would rather like to learn the difference between these specific concepts.
For reference the question is An LC-3 instruction ADD R1,R2, #45 produces an error. It will be caught at a. assembly time b. link time c. run time d. compile time. Rather than just finding out the answer what would rather like to know is what is the difference between these and how do they differ when it comes to error handling?
Using the C programming language as an example the 4 steps to create an executable program Preprocessing, Compiling, Assembling, and Linking.
Compile time
These are generally common and are caused by a malformed user program that the compiler can't process, things such as forgetting a semicolon can cause a compiler error.
Assembly Time
Something went wrong with the assembler. This includes using instructions incorrectly as above, not defining a LABEL but using it in an instruction etc.
Link Time
As part of the C compile process to form an executable many object files generated by the assemble step are linked together. In C programming you can specify that some symbol is defined externally via the extern keyword, other things like function prototypes will tell the compiler a function is defined somewhere.
The linker will resolve where those variables/functions live. If you haven't declared a function/variable and something references it then you will get a undefined reference error. Same for if something is defined multiple times.
Run Time
An error occurred during running your program, this is something such as accessing a pointer that is null, or dividing by zero.

will C++ 11 extern template help to reduce executable file size

I am using g++ on linux with C++ generic programming. I am not using "extern template" key word now, because I tried and sometimes it ended up with "undefined reference to". I know this is probably my fault, but I wouldn't take this risk. My question is, in addition to reducing compile time, will this key word also help to reduce the executable file size? I am suspecious that the executable file has multiple same objects in different modules in the same executable file...
No, it will not reduce final executable size. The "extern template" prevents implicit instantiation in the translation unit. Without "extern template" implicit instantiation of the
same template may happen in several translation units, but the linker will still remove redundant copies and leave only a single.

Xcode error: Command /Developer/usr/bin/clang++ failed with exit code 1 due to duplicate symbol

I'm trying to write a program in C++ which runs Conway's Game of Life. I think I have everything that I need, but I'm having some trouble with compiling.
The program is composed of four files: gameoflife.h, a header file which contains my global constants and function declarations, gameoflife.cpp, which defines the functions, main.cpp, which uses the functions, and seeds.cpp, which contains a list of predefined seeds to be used.
When I go to compile the application, I seem to have a clash of duplicate symbols between main.cpp and gameoflife.cpp over an array called currGen which is declared in gameoflife.h.
Both main.cpp and gameoflife.cpp include gameoflife.h, which of course is necessary so that they have access to the global constants and function declarations.
The exact error I receive is the following:
duplicate symbol _currGen in /(same_path)/ConwaysGameOfLife.build/Objects-normal/
x86_64/gameoflife.o and
/(same_path)/ConwaysGameOfLife.build/Objects-normal/x86_64/main.o
for architecture x86_64
Command /Developer/usr/bin/clang++ failed with exit code 1
I've looked around on Stack Overflow but haven't found anything which matches my problem. Any help would be greatly appreciated!
You are probably defining the variable currGen in your header file, not just declaring it.
There needs to be exactly one definition, in one .cpp file. The .h file should just declare it, using extern.
This answer goes into much more detail.

Why gcc gives error of unused variable for local variables but not for global variables?

I have a question regarding gcc. Why I get an error of unused variable when I define the variable locally in a function but not when the variable is global in a unique file?.
I can understand that it can be use for someone else, but to do that then I need to put the external word right?
Thanks in advance.
The compiler has no way of knowing if a global variable is used - it could be used from a compilation unit written in a completely different language, for example.
If by "global in a unique file", you mean "int x;" outside of any function, the it's not the compilers job to detect that, the variable needs to be available to the linker in case another compilation unit needs it (such as errno).
If you meant "static int x" where it's not made available to the linker, this is probably just a choice made by GCC. I don't believe compilers are required to notify of this and it does no real damage other than wasting a few bytes in your address space.
Because global variables can be used on any other place that the compiler cannot known. For instance on a external library o program.
Unused locals can be determined by the compiler. Unused globals can only be determined by the linker, since they can be shared across object files.
In general, the linker doesn't do warnings for code-gen.
When the variable is global, the compiler has not full visibility across all the compilation units in the project - the variable could be modified in another compilation unit. The linker is able to tell that it is unused, probably it will remove it from the object file.
Because if it's global it can be used by another module that gets linked in later.
It's a common idiom to have all your globals defined in a single file. That file may not even have any code, much less code that uses all the variables.
I have encountered the same question when I build the dalvikVM in android2.3 and I got the key of the point. It is because that the parameters of the compiler is too strict:
LOCAL_CFLAGS += -Werror.

Resources