why use gcc and g++ compiler drivers for c and c++ - c++

I have ported a project to an arm cortex M7 chip, and am mucking around with makefiles for the first time, im using the gnu-gcc compiler collection.
Is it advisable to compile "c" code with the gcc driver and, compile the "c++" (app) code with the g++ driver, and then link. The c code is all low level (header files)register access addresses etc and contains no functions (yet) or attached source files.
Or can i compile all with the g++ compiler if the header files can be modified to compile with g++ if needed.
I have it set so gcc is compiling the c files, and g++ is compiling c++ and linking.

The only differences between gcc and g++ are that:
when the driver is used to invoke the linker, g++ causes libstdc++ to be linked as part of "stdlibs", while gcc will link only libc.
g++ will compile .c, .h and .i files as C++ unless the -x option is specified.
Both drivers will compile C or C++ depending on either the filename extension, or command-line switches. If you invoke the compiler-driver for compilation only and invoke the linker (ld) directly, using gcc or g++ -x, it makes no difference which you use.
Equally, if you invoke the gcc driver for C++ code and explicitly link stdlibc++ it also makes no difference - so long as your crt0.o is not C-only - a C++ runtime start-up must invoke global static constructors before main()) - this is likely to already be the case.
The definitive word from the documentation:
3.3 Compiling C++ Programs
C++ source files conventionally use one of the suffixes ‘.C’, ‘.cc’, ‘.cpp’, ‘.CPP’, ‘.c++’, ‘.cp’, or ‘.cxx’;
C++ header files often use ‘.hh’, ‘.hpp’, ‘.H’, or (for shared
template code) ‘.tcc’; and preprocessed C++ files use the suffix
‘.ii’. GCC recognizes files with these names and compiles them as C++
programs even if you call the compiler the same way as for compiling C
programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program
that calls GCC and automatically specifies linking against the C++
library. It treats ‘.c’, ‘.h’ and ‘.i’ files as C++ source files
instead of C source files unless -x is used. This program is also
useful when precompiling a C header file with a ‘.h’ extension for use
in C++ compilations. On many systems, g++ is also installed with the
name c++.
When you compile C++ programs, you may specify many of the same
command-line options that you use for compiling programs in any
language; or command-line options meaningful for C and related
languages; or options that are meaningful only for C++ programs. See
Options Controlling C Dialect, for explanations of options for
languages related to C. See Options Controlling C++ Dialect, for
explanations of options that are meaningful only for C++ programs.
If you want to use just one, I suggest you use gcc and separately invoke the linker or explicitly link -libstdc++. That way the compilation mode will be dependent on the filename extension. Using g++ -x to compile C code is just going to cause confusion.

Related

Undefined reference error to std::string and std::vector class methods [duplicate]

Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.

Should c++ object files be linked through g++ only?

I read somewhere that c++ object files must be linked only through g++ not gcc. Is it true? if yes, then how to link object files belong to c, c++ and asm?
If you use g++ to link, then it will automatically link with the C++ runtime library. If you link with gcc you have to link with the runtime manually.
That's the only difference.
The gcc and g++ programs are only special front-end wrapper programs, that invoke the correct preprocessor, compiler, assembler and linker for the files provided.
Yes, you have to use G++ to link C++ due to name mangling.
See the topic here https://en.wikipedia.org/wiki/Name_mangling
C++ names are C-abi compatible, you can link C++ object files to C code.

Forcing Clang to link with C++ runtime

I have a project containing a mixture of C and C++ source. It currently builds with GCC on OS X. The project has bespoke build scripts which invoke the gcc command to compile both the C and C++ source, and separately invoke the linker.
I am now trying to get it building with Clang.
Invoking clang does compile the source files correctly; it distinguishes between .c and .cpp source files, and compiles for the appropriate language in each case. I have problems at link time, though. When the linker is invoked as clang, the C++ runtime libraries are not linked in, causing a build error due to missing symbols.
I can link successfully when I set clang++ as the build tool, but this then causes compile-time errors and warnings; it really doesn't like compiling C source with the C++ compiler.
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
...
/usr/include/stdio.h:250:49: error: redefinition of parameter 'restrict'
I have to specify a single tool for the build scripts to use as the compiler/linker, so I need to do a simple substitution of clang in place of gcc.
Is there any way I can persuade clang (not clang++) to link with the C++ runtime libraries?
Options such as -stdlib=libc++ don't work.
You should just be able to use the normal linker flag, same as you'd do for gcc: clang -lc++ or clang -lstdc++ depending on which implementation you want. (and you should want libc++)

K&R style function definition compile using g++

When compiling a c file that uses old style function definition like
int foo(a)
int a;
{
...
}
g++ will give and error: ‘a’ was not declared in this scope.
gcc can parse this.
Is there a way to let g++ recognize this?
This comes up as an issue to me because I'm compiling a mix of c and c++ files.
A related question is what's the standard practice
of building this type of mixed source? Running g++ on all files or only the cc files? The former is convenient but keeps getting me some trouble because of the inconsistencies between c and c++ specification(for example, char[4]="four";)
Is there a way to let g++ recognize this?
This syntax is not supported in C++.
Running g++ on all files or only the cc files?
See e.g. Compiling C++ programs from the GCC docs:
C++ source files conventionally use one of the suffixes .C', .cc, .cpp, .CPP, .c++, .cp, or .cxx; C++ header files often use .hh, .hpp, .H, or (for shared template code) .tcc; and preprocessed C++ files use the suffix .ii. GCC recognizes files with these names and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program that calls GCC and treats .c, .h and .i files as C++ source files instead of C source files unless -x is used, and automatically specifies linking against the C++ library. This program is also useful when precompiling a C header file with a .h extension for use in C++ compilations.
So two possibilities:
Run gcc on C files, and g++ on C++ files.
Run gcc on all files.
In both cases you will need to link with g++ (or gcc -lstdc++).
Oli is correct: C++ doesn't support old-style function definitions.
Compile C with a C compiler (such as gcc).
Compile C++ with a C++ compiler (such as g++).
They're two different (though closely related) languages. You can use C++'s extern "C" feature to invoke C code from C++ and vice versa; see section 32 of the C++ FAQ Lite for more information.
If you are going to compile both C and C++, you are better off compiling always with gcc (it will choose the language based on the file extension) than g++ (will always compile as C++). You will need to change your linker options to include C++ standard library (and -lm if you use it) as those are automatically added by g++ but not gcc.
Alternatively, a better option is to call the g++ for C++ and gcc for C files. That should not be too hard to manage by configuring the build system.

Any difference in linking with gcc vs. g++?

Are there any differences in the linking process between gcc and g++?
I have a big C project and I just switched part of the code to C++. The code isn't using std C++ library yet, so -llibstdc++ isn't needed for now.
The main difference is that (assuming the files are detected as C++) g++ sets up the flags needed for linking with the C++ standard library. It may also set up exception handling. I wouldn't rely on the fact that just because your application doesn't use the standard library that it isn't needed when compiled as C++ (for example the default exception handler).
EDIT: As pointed out in comments you'll have trouble with any constructors (that do work) for static objects as well as not getting virtual function tables (so if you're using those features of C++ you still need to link that library).
EDIT2: Unless you're using C99 specific code in your C project I would actually just switch to compiling the whole thing as C++ as the first step in your migration process.
gcc and g++ are both just driver programs that don't do anything other than calling other programs, so you can use the -v option to see exactly what they do -- what other programs they invoke with what args. So you can see exactly what the difference is between linking with gcc and g++ for the specific version and architecture of gcc that you happen to have installed. You can't rely on that staying the same if you want portability, however.
Depending on what you are doing, you might also be interested in the -### argument
I think that the g++ linker will look for the CPP mangled function names, and it is different from the C ones. I'm not sure gcc can cope with that. (Provided you can explicitly use the C version rather than the C++ one).
Edit:
It should work if you have
extern "C" {
<declarations of stuff that uses C linkage>
}
in your code and the object file has been compiled with g++ -c. But I won't bet on this.