What are the difference between the 3 compilers CC, gcc, g++ when compiling
C and C++ code in terms of assembly
code generation, available libraries, language features, etc.?
The answer to this is platform-specific; what happens on Linux is different from what happens on Solaris, for example.
The easy part (because it is not platform-specific) is the separation of 'gcc' and 'g++':
gcc is the GNU C Compiler from the GCC (GNU Compiler Collection).
g++ is the GNU C++ Compiler from the GCC.
The hard part, because it is platform-specific, is the meaning of 'CC' (and 'cc').
On Solaris, CC is normally the name of the Sun C++ compiler.
On Solaris, cc is normally the name of the Sun C compiler.
On Linux, if it exists, CC is probably a link to g++.
On Linux, cc is a link to gcc.
However, even on Solaris, it could be that cc is the old BSD-based C compiler from /usr/ucb. In practice, that usually isn't installed and there's just a stub that fails, wreaking havoc on those who try to compile and install self-configuring software.
On HP-UX, the default 'cc' is still a K&R-only C compiler installed to permit relinking of the kernel when necessary, and unusable for modern software work because it doesn't support standard C. You have to use alternative compiler names ('acc' IIRC). Similarly, on AIX, the system C compiler goes by names such as 'xlc' or 'xlc32'.
Classically, the default system compiler was called 'cc' and self-configuring software falls back on that name when it doesn't know what else to use.
POSIX attempted to legislate its way around this by requiring the programs c89 (originally) and later c99 to exist; these are the compilers compatible with the ISO/IEC 9899:1989 and 9899:1999 C standards. It is doubtful that POSIX succeeded.
The question asks about the differences in terms of features and libraries. As before, the answer is platform specific in part, and generic in part.
The big divide is between the C compilers and the C++ compilers. The C++ compilers will accept C++ programs and will not compile arbitrary C programs. (Although it is possible to write C in a subset that is also understood by C++, many C programs are not valid C++ programs). Similarly, the C compilers will accept C programs and will reject most C++ programs (because most C++ programs use constructs not available in C).
The set of libraries available for use depends on the language. C++ programs can usually use C libraries on a given platform; C programs cannot usually use C++ libraries. So, C++ has a larger set of libraries available.
Note that if you are on Solaris, the object code produced by CC is not compatible with the object code produced by g++ -- they are two separate compilers with separate conventions for things such as exception handling and name mangling (and the name mangling is deliberately different to ensure that incompatible object files are not linked together!). This means that if you want to use a library compiled with CC, you must compile your whole program with CC. It also means that if you want to use one library compiled with CC and another compiled with g++, you are out of luck. You have to recompile one of the libraries at least.
In terms of quality of assembler generated, the GCC (GNU Compiler Collection) does a very good job. But sometimes the native compilers work a bit better. The Intel compilers have more extensive optimizations that have not yet been replicated in GCC, I believe. But any such pontifications are hazardous while we do not know what platform you are concerned with.
In terms of language features, the compilers all generally hew fairly close to the current standards (C++98, C++2003, C99), but there are usually small differences between the standard language and the language supported by the compiler. The older C89 standard support is essentially the same (and complete) for all C compilers. There are differences in the darker corners of the language. You need to understand 'undefined behaviour', 'system defined behaviour' and 'unspecified behaviour'; if you invoke undefined behaviour, you will get different results at different times. There are also many options (especially with the GCC) to tweak the behaviour of the compiler. The GCC has a variety of extensions that make life simpler if you know you are only targetting that compiler family.
CC is an environment variable referring to the system's C compiler. What it points to (libraries accessible, etc) depend on platform. Often it will point to /usr/bin/cc, the actual c complier (driver). On linux platforms, CC almost always points to /usr/bin/gcc.
gcc is the driver binary for the GNU compiler collection. It can compile C, C++, and possibly other languages; it determines the language by the file extension.
g++ is a driver binary like gcc, but with a few special options set for compiling C++. Notably (in my experience), g++ will link libstdc++ by default, while gcc won't.
I wanna add just one information what cc in Linux. It is linked with gcc. To check it.
Similarly, the same thing with c++.
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ whereis c++
c++: /usr/bin/c++ /usr/include/c++ /usr/share/man/man1/c++.1.gz
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ ls -l /usr/bin/c++
lrwxrwxrwx 1 root root 21 Jul 31 14:00 /usr/bin/c++ -> /etc/alternatives/c++
uddhavpgautam#UbuntuServer1604:~/Desktop/c++$ ls -l /etc/alternatives/c++
lrwxrwxrwx 1 root root 12 Jul 31 14:00 /etc/alternatives/c++ -> /usr/bin/g++
Related
Can you use MVAPICH2 to compile a fortran 2003 programme?
MVAPICH2 states that a) it provides its own compilers and b) it provides the mpif77 and mpif90 wrappers (which both point to e.g. /opt/mvapich2-2.3.1/bin/mpifort). I can't find any docs which help with this.
MPI implementations (MVAPICH is one of many MPI implementations) only provide wrappers around other compilers. They do not provide any "own" compilers. You can compile whichever Fortran does your compiler support.
The build of MVAPICH you download somewhere may be already compiled to be used with some specific compiler, but that does not mean MVAPICH provides that compiler. Similarly, if you buy a compiler suite, it can come with an MPI library (like MVAPICH) pre-compiled.
It is customary to call the mpif90 wrapper to compile any modern Fortran but often the difference from mpif77 is very small, if any at all. Some compilers also provide mpifort or some other wrapper name, which does not explicitly contain any Fortran standard version.
Most modern compilers you will find support most, if not all, features of Fortran 2003. It depends on the exact version you have.
clang++ and g++ are ABI incompatible, even for things as core as standard containers, according to, e.g., the clang++ website.
Debian ships with C++ shared libraries, i.e. libboost, etc... that are compiled with ~something and user programs using both compiler generally work, and the library names aren't mangled with the compiler that was used for them. When you install clang, debian doesn't go and pull in duplicate versions of every C++ library installed on your system.
What's the deal? Is the ability of clang to link against distro-provided C++ libraries just way stronger than the (thankfully cautious) compiler devs describe it to be?
even for things as core as standard containers
Standard containers are not all that "core". (For typical implementations) they are implemented entirely in valid C++ in headers, and if you compile the same headers with G++ and Clang++ you'll get ABI compatible output. You should only get incompatibilities "even for things as core as standard containers" if you use different versions of the container headers, not just by using Clang instead of GCC.
Both GCC and Clang conform to a cross-vendor, cross-platform C++ ABI (originally developed for the Itanium architecture, but also used for x86, x86_64, SPARC etc.) The really core things such as class layout, name mangling, exception handling, vtables etc. are specified by that ABI and Clang and GCC both follow it.
So in other words, if you compile the same source with GCC and Clang you'll get ABI-compatible binaries.
If you want to understand this stuff better see my What's an ABI and why is it so complicated? slides.
G++ and Clang are for the vast majority completely ABI compatible. Furthermore, ABI incompatibilities for Standard containers are properties of the standard library implementation (libstdc++ or libc++), not the compiler. Therefore, there is no need for any re-compilation.
Clang could never have gotten off the ground if it was not ABI compatible with g++, as it would be basically unusable without a pre-existing large following. In fact, Clang is so compatible with GCC, they ape virtually all of g++'s command-line interface, compiler intrinsics, bugs, etc, so that you can literally just drop in Clang instead of G++ and the vast majority of the time, everything will just work.
This probably will not answer the exact question correctly:
Some time ago I tried to compile some object files wih gcc, another object files with clang. Finally I linked everything together and it worked correctly.
I believe Linux distributions uses gcc, because I examined some Makefile's of Ubuntu and CentOS and they used gcc.
I want to create a program with a mix of C++ and D, and I would like to be able to work on it as a single project.
My understanding is that I can use some D compiler to output *.obj files, then I can do the same with some C++ compiler, and then link all of the *.obj files into a single binary, is this correct?
If this is correct, can I use any C++ compiler with any D compiler? Or am I restricted to certain combinations like, DMD-DMC, LDC-Clang, and GDC-GCC?
Which linker do I use?
And which standard library do I use?
In theory, you could mix the compilers, but in practice you'd have object file format and standard library mixing issues from time to time, especially on 32 bit Windows. It'd be hard there, but not too bad elsewhere since most things are based on de-facto standards like MSVC and gcc.
Win32: use dmc++ (the digital mars compiler and C runtime) with dmd OR g++ and gdc. Other combinations can be done but are messy. Best way to mix code in Win32 across compiler families is to build a DLL with a C or COM api and use that from D.
Win64: Since dmd uses the 64 bit Microsoft format and C library, you should have little trouble mixing dmd with Visual C++ code. I'm not sure about g++ on Windows64 with dmd.
Most other platforms, including Linux: dmd works along well with g++, as does gdc + gcc. I'm not sure if ldc and g++ are compatible, but ldc should work fine with other LLVM based commpilers on any platform too.
If I build a static library with llvm-gcc, then link it with a program compiled using mingw gcc, will the result work?
The same for other combinations of llvm-gcc, clang and normal gcc. I'm interested in how this works out on Linux (using normal non-mingw gcc, of course) and other platforms as well, but the emphasis is on Windows.
I'm also interested in all languages, but with a strong emphasis on C and C++ - obviously clang doesn't support Fortran etc, but I believe llvm-gcc does.
I assume they all use the ELF file format, but what about call conventions, virtual table layouts etc?
Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.
C++ is not portable between compilers in the slightest; different compilers use different virtual table calls, constructors, destruction, name mangling, template implementations, etc. As a rule you should assume objects from one C++ compiler will not work with another.
However yes, at the time of writing Clang++ is able to use GCC/C++ compiled libraries as well; I recently set up a rig to compile C++ programs with clang using G++'s standard runtime library and it compiles+links just fine.
I don't know the answer, but slide 10 in this presentation seems to imply that the ".o" files produced by llvmgcc contain LLVM bytecode (.bc) instead of the usual target-specific object code, so that link-time optimization is possible. However, the LLVM linker should be able to link LLVM code with code produced by "normal" GCC, as the next slide says "link in native .o files and libraries here".
LLVM is a Linux tool, I have sometimes found that Linux compilers don't work quite right on Windows. I would be curious whether you get it to work or not.
I use -m i386pep when linking clang's .o files by ld. llvm's devotion to integrating with gcc is seen openly at http://dragonegg.llvm.org/ so its very intuitive to guess llvm family will greatly be cross-compatible with gcc tool-chain.
Sorry - I was coming back to llvm after a break, and have never done much more than the tutorial. First time around, I kind of burned out after the struggle getting LLVM 2.6 to build on MinGW GCC - thankfully not a problem with LLVM 2.7.
Going through the tutorial again today I noticed in Chapter 5 of the tutorial not only a clear statement that LLVM uses the ABI (Application Binary Interface) of the platform, but also that the tutorial compiler depends on this to allow access to external functions such as sin and cos.
I still don't know whether the compatible ABI extends to C++, though. That's not an issue of call conventions so much as name mangling, struct layout and vtable layout.
Being able to make C function calls is enough for most things, there's still a few issues where I care about C++.
Hopefully they fixed it but I avoid llvm-gcc because I (also) use llvm as a cross compiler and when you use llvm-gcc -m32 on a 64 bit machine the -m32 is ignored and you get 64 bit ints which have to be faked on your 32 bit target machine. Clang does not have that bug nor does gcc. Also the more I use clang the more I like. As to your direct question, dont know, in theory these days targets have well known or used calling conventions. And you would hope both gcc and llvm conform to the same but you never know. the simplest way to find this out is to write a couple of simple functions, compile and disassemble using both tool sets and see how they pass operands to the functions.
I am planning to compile a static library (mylib.a) with gcc 4.7.1. I want to take the advantages of C++11, so -std=c++11 is used. The platform, where I compile this lib is x86_64 SLES 11 with glibc-2.8.
Then I want to link this static library on a legacy platform with a legacy code, therefore I must use gcc 4.1.2 for linking and compiling the legacy code. So in my library headers I will not use any C++11 specific code. Also I will link libstdc++.a from gcc.4.7.1. The platform, where I want to link mylib.a, libstdc++.a(gcc4.7.1) and the legacy object files is x86_64 SLES 10 with glibc-2.4.
I tried all of this mess with some dummy C++11 code (std::async()) in mylib.a and it worked. I think this is possible only becuase of the ELF requiriements. Am I thinking correctly, or ELF has nothing to do with it? What kind of errors should I expect if mylib.a will contain some truly complex logic?
Linux has a C++ Application Binary Interface (ABI), which has been around for a while. This means that the calling conventions and name mangling across compilers on Linux is fixed. Therefore, as long as the libraries are compatible, you should be able to compiler with different compilers (or different versions of the same compiler) and have code which correctly and reliably links together.
Not entirely the ELF requirements per se...
GCC guarantees binary compatibility all the way back to some ancient version of 3. As long as the libstdc++ you're linking to has the new library features, there's no reason you can't use them. You will just have to stay away from the new language and library features in code compiled with GCC 4.1.2.