I am learning C (still very much a beginner) on Linux using the GCC compiler. I have noticed that some libraries, such as the library used with the math.h
header, need to be linked in manually when included. I have been linking in the libraries using various flags of the form -l[library-name]
, such as -lm
for the above-mentioned math library.
However, after switching from the command line and/or Geany
to Code::Blocks
, I noticed that Code::Blocks
uses g++
to compile the programs instead of the gcc
that I am used to (even though the project is definitely specified as C). Also, Code::Blocks
does not require the libraries to be manually linked in when compiling – libraries such as the math library just work.
I have two questions:
Firstly, is it “bad” to compile C programs with the g++
compiler? So far it seems to work, but after all, C++ is not C and I am quite sure that the g++
compiler is meant for C++.
Secondly, is it the g++
compiler that is doing the automatic linking of the libraries in Code::Blocks
?
2
Both gcc and g++ are frontends to the GNU compiler collection. You should use the former for compiling and linking C code, and the latter for performing the same actions on C++ code. One of the strongest arguments for maintaining the distinction is that C is not a subset of C++.
If you link using g++ it will automatically link in the C++ standard library. Since the C standard library is part of the C++ standard library, the math library is included as well. This is why you do not need to link in the math library manually.
Firstly, is it “bad” to compile C programs with the g++ compiler?
Define “bad”.
There are a few things which may cause a valid C program to compile in C++ with a different semantic, if my experience is pertinent, you have more chances to find UB handled differently when changing the version of your C compiler than to meet them.
A C++ compiler will not compile some valid C programs, so compiling C with a C++ compiler will restrict you to their common subset, which is a stricter version of C. Restricting yourself to that C dialect is not not idiomatic (the major difference is the need to cast void* when another pointer type is needed) do so but quite a few projects started to use C++ in that way. They where using a C++ compiler to get a more type-safe version of C and then decided to allow the use of the additional features, one by one, as they deemed them pertinent. (The latest and more public example is gcc itself. GCC started to be written in K&R C, then mandated an ANSI C compiler, then was restricted to the common subset of ANSI C and C++, and now they are starting to use C++, another quite public example is that the examples in the second edition of K&R C were compiled with a C++ compiler — but I think C++ was tightened since as it seems to me that some examples won’t compile with a current C++ compiler).
Note that if you only use C++ compilers, you’ll quickly introduce C++ dependencies in it.
Note also that of the new things in C99 and C11 are more subject to be different in C++.
Secondly, is it the g++ compiler that is doing the automatic linking of the libraries in Code::Blocks?
When used to link, a compiler always link a default set of libraries. That set for gcc doesn’t included libm, it is included in the default set for g++. G++ will not auto-detect additional libraries if they are needed (AFAIK neither will Code::Blocks), libm
is a very particular case (some will argue that the fact that gcc doesn’t link it by default is a bug in gcc).
1