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.
Static
With a statically linked application, everything that you need to run the application is part of the application itself. It depends on nothing else.
If there is a fatal error in a dynamically linked library, it doesn't 'care'.
If the dynamically linked version of a library it uses isn't there (someone accidentally removed /lib
on a unix system?) it doesn't care.
It requires no additional installs of libraries to run on any binary compatible platform. You download the app and you can run it.
There is an entire directory of statically linked applications on every unix system in /sbin
that are guaranteed to always work even if significant parts of the system are otherwise broken or missing. reboot
? halt
? ifconfig
? mount
? fsck
? ping
? Those are likely all in /sbin
so that even if the libraries are missing or corrupt (or not mounted because they're on a network filesystem...) you can still run those commands to get the system working (and mount that networked file system with the libraries you are looking for).
True story: One sysadmin many years ago, back when an 80 megabyte hard disk was big was looking for some space. Standard compiles included debugging/symbol information and that took a few kilobytes in each binary. So, he found every executable on the system and ran strip on it. Did you know that shared libraries are 'executables' on many systems? Removing the symbol information from them prevents anything from dynamically linking to them... oops. The only things working where those in /sbin. Fortunately, there was enough there that he was able to mount the other system of the same type and copy the shared libraries back over to the messed up system...
Dynamic
You want to update a library? No problem. Just put the library in the proper spot and all is well. Yea, that's a bit simplistic, but its the idea.
$ ldd /bin/date
linux-vdso.so.1 => (0x00007fff6ffff000)
librt.so.1 => /lib64/librt.so.1 (0x00007f54ba710000)
libc.so.6 => /lib64/libc.so.6 (0x00007f54ba384000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f54ba167000)
/lib64/ld-linux-x86-64.so.2 (0x00007f54ba919000)
Those are all libraries that are already loaded somewhere that you don't have to have in your application. There can be some savings in disk space size because you don't need to put a full copy of libc or any other library as part of your application.
System patching becomes easier. Instead of needing to push out a patch for everything in /bin because something changed (you need to do this for /sbin), you just push out a new shared library object and update the symbolic link chain in /lib.
Drop in replacements become possible. Just provide the same API and symbols, drop in the new library and update the symbolic link chain and all should be good.
On a system that runs multiple processes (almost all of them these days... but it was a significant distinction back in old times) static libraries meant that each application running had a full copy of its libraries taking up memory resources. Shared libraries means that they can all just point to the same spot in already loaded memory.
Statically linking an application can be considered a derivative work of the libraries. This becomes an issue with GPL software. There are differing opinions on if dynamically linking a GPL licensed library creates a derivative work.
Dynamic linking allows for plugins. The application loads the plugins and dynamically calls the functions available to it.
Multiple languages can use the same calling conventions and call a dynamic library. Look at Java for an example there - dynamic linking means that Clojure, Scala, Groovy, etc... with dynamic linking they can all use the same shared libraries. Alternatively look at all the different languages that can invoke a .DLL on windows.
Related reading:
Best Answer
Linking code (using the linker, e.g.
ld
often started bygcc
orgfortran
compilation commands) written in two different languages is implementation specific. It is often called foreign function interface. It depends upon calling conventions specific to the implementations.On Linux, with code compiled by
gfortran
andgcc
(both from the GCC compiler) is quite easy (in particular because both share a common middle-end and back-end layers of the Gnu Compiler Collection). Thegfortran
documentation has a chapter about mixed language programmingBTW, you can make two processes (e.g. running two different -or the same- programs, perhaps coded in two different languages) communicate using Inter-process communication; this is provided by the operating system so is OS specific. On Linux and POSIX you could use pipe(7)-s, socket(7)-s, in particular unix(7) ones (and poll(2) them appropriately in some event loop), shared memory (see shm_overview(7) & sem_overview(7) for synchronization with semaphores), etc. Read Advanced Linux Programming. You might be interested by Remote Procedure Calls (e.g. JSON-RPC, ....), MPI, etc...
PS. Don't call IPC linking. When talking about software, linking means using the linker (e.g. to merge & mix code from various object files and libraries into a single executable).