22

Objective-C has a runtime that translates its syntax into functions that are organized and compiled. Does C have a runtime library? Also, if anyone can answer the question, what are the steps GCC takes during C compilation? e.g. main.c >> main.s >> main.bin

jscs
  • 63,694
  • 13
  • 151
  • 195
George Morgan
  • 669
  • 10
  • 23
  • 3
    http://en.wikipedia.org/wiki/C_runtime – Robert Harvey Oct 16 '12 at 03:30
  • Microsoft calls it a runtime. http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.110).aspx – i_am_jorf Oct 16 '12 at 03:35
  • 2
    You seem to be unclear on what a runtime system does. It does not "translate [...] syntax into functions"; that's the compiler's job. The runtime in ObjC primarily provides the object infrastructure: creation of classes, sending of messages, and so forth. (There are other pieces to it, of course.) – jscs Oct 16 '12 at 03:37

3 Answers3

13

Yes, the C language features a standard library; that is, a number of standard macros, routines and types one can use in his programs, apart from any in the core language itself.

In popular implementations, there is a separate library file containing the code for the C standard library. For example, in GNU/Linux environments, the GNU C library (libc) is almost always present. Microsoft provides the msvcrt.dll runtime library for the Windows system, and so on.

Also, the C standard library might not be available in freestanding implementations. Sometimes it is possible to compile a program without linking against the C standard library from your system. As an example, the Windows API is well known for behaving as a freestanding C programming environment (although one might need to link against other system libraries specific to Windows).

Regarding GCC, the following illustrates briefly the compilation pipeline:

  1. The input source is preprocessed with GNU cpp, resulting in a translation unit. (Actually, as Basile pointed out, nowadays no cpp process is created; the entire preprocessing work is done within cc1. Nevertheless, the resulting behavior is most likely the same as with cpp.)
  2. The translation unit is then interpreted and compiled to assembly source with GCC cc1;
  3. The assembly source is then assembled into object code with GNU as;
  4. Finally, object files and libraries are linked together to produce a binary image with GNU ld.

Naturally, each of these steps may be altered or not executed at all depending on the driver options; the above is just a rough explanation of the overall process.

alecov
  • 4,882
  • 2
  • 29
  • 55
  • This is wrong today: with recent GCC (even GCC from the early 2000s), the preprocessing and compilation is done by `cc1` and there is no more any `cpp` process – Basile Starynkevitch Oct 16 '12 at 04:49
6

C has a standard library (libc on Linux, which provides standard functions like those in <stdio.h> such as fprintf and in <stdlib.h> such as malloc and also all the system calls), and even when you use gcc in free standing mode with gcc -ffreestanding (e.g. to compile a libc or some kernel) it links a tiny libgcc library which provides the functionality built-in the language (e.g. 64 bits addition on 32 bits platforms).

To learn what the gcc command is doing, pass it the -v flag. (Don't forget to take the habit to always compile with -Wall to get warnings and -g to get the debug information), e.g.

 % gcc -v -g -Wall hello.c -o hello
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-4) 
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -quiet -v -imultiarch x86_64-linux-gnu hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -g -Wall -version -o /tmp/ccsWt3UC.s
GNU C (Debian 4.7.2-4) version 4.7.2 (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C (Debian 4.7.2-4) version 4.7.2 (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c5f63dedeacd449634699df94fe3d914
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccO5i3pU.o /tmp/ccsWt3UC.s
GNU assembler version 2.22 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.22
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 --sysroot=/ --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. /tmp/ccO5i3pU.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o

Notice that collect2 is the linker wrapped to do additional things, and that libc.so gets used by almost every Linux executable (because it is wrapping syscalls).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

C has a standard library (e.g., strlen, malloc, etc.)

The steps are: compile your code that uses the standard library, then link your code to the standard library. libc can be contained in either a static library or a dynamic library, depending; usually both are available.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111