compilation how - What's an object file in C?
to read (6)
Object code are codes tat are dependent on functions, symbols, text to run the machine. Just like old telex machines which required teletyping to send signals to other telex machine. In the same way processor requires binary code to run machine. Object file is like binary code but is not linked. Linking creates additional files so that user does not have to have compiler like c language. User can directly open the exe file once the object file is linked with some compiler like c language , or vb etc.
I am reading about libraries in C but I have not yet found an explanation on what an object file is. What's the real difference between any other compiled file and an object file?
I would be glad if someone could explain in human language.
An object file is the real output from the compilation phase. It's mostly machine code, but has info that allows a linker to see what symbols are in it as well as symbols it requires in order to work. (For reference, "symbols" are basically names of global objects, functions, etc.)
A linker takes all these object files and combines them to form one executable (assuming that it can, ie: that there aren't any duplicate or undefined symbols). A lot of compilers will do this for you (read: they run the linker on their own) if you don't tell them to "just compile" using command-line options. (
-c is a common "just compile; don't link" option.)
An Object file is the compiled file itself. There is no difference between the two.
An executable file is formed by linking the Object files.
Object file contains low level instructions which can be understood by the CPU. That is why it is also called machine code.
This low level machine code is the binary representation of the instructions which you can also write directly using assembly language and then process the assembly language code (represented in English) into machine language (represented in Hex) using an assembler.
Here's a typical high level flow for this process for code in High Level Language such as C
--> goes through pre-processor
--> to give optimized code, still in C
--> goes through compiler
--> to give assembly code
--> goes through an assembler
--> to give code in machine language which is stored in OBJECT FILES
--> goes through Linker
--> to get an executable file.
This flow can have some variations for example most compilers can directly generate the machine language code, without going through an assembler. Similarly, they can do the pre-processing for you. Still, it is nice to break up the constituents for a better understanding.
There are 3 kind of object files.
Relocatable object files
Contain machine code in a form that can be combined with other relocatable object files at link time, in order to form an executable object file.
If you have an
a.c source file, to create its object file with GCC you should run:
gcc a.c -c
The full process would be: preprocessor (cpp) would run over a.c. Its output (still source) will fed into the compiler (cc1). Its output (assembly) will fed into the assembler (as), which will produce the
relocatable object file. That file contains object code and linking (and may debugging if
-g was used) metadata, and is not directly executable.
Shared object files
Special type of relocatable object file that can be loaded dynamically, either at load time, or at run time. Shared libraries are this kind of objects.
Executable object files
They contain machine code that can be directly loaded into memory (by the loader, e.g execve) and subsequently executed.
The result of running the linker over multiple
relocatable object files is an
executable object file. The linker merges all the input object files from the command line, from left-to-right, by merging all the same-type input sections (e.g.
.data) to the same-type output section. It uses
symbol resolution and
When linking against a
static library, the functions that are referenced in the input objects are copied to the final executable.
dynamic libraries, a symbol table is created instead that will enable a dynamic linking with the library's functions/globals. Thus, the result is a partially executable object file, as it depends on the library. (in simple words, if library is gone, the file can no longer execute).
The linking process can be done as follows:
ld a.o -o myexecutable
gcc a.c -o myexecutable will invoke all the commands mentioned at point 1 and at point 3 (cpp -> cc1 -> as -> ld1)
1: actually is collect2, which is a wrapper over ld.
An object file is just what you get when you compile one (or several) source file(s).
It can be either a fully completed executable or library, or intermediate files.
The object files typically contain native code, linker information, debugging symbols and so forth.
size_tis a type that can hold any array index. This means that, logically, size_t should be able to hold any pointer type
Not necessarily! Hark back to the days of segmented 16-bit architectures for example: an array might be limited to a single segment (so a 16-bit
size_t would do) BUT you could have multiple segments (so a 32-bit
intptr_t type would be needed to pick the segment as well as the offset within it). I know these things sound weird in these days of uniformly addressable unsegmented architectures, but the standard MUST cater for a wider variety than "what's normal in 2009", you know!-)