In systems programming, oftentimes, you're not always just writing code against an API; often, you need to care about ABI compatibility as well. A famous ABI break happened when GCC released its fifth version, with one of the major changes being the change of the class layout of std::string. This meant that libraries working with older GCC versions (or still using the new ABI in newer versions, which is still a thing in recent GCC releases) would not work with code written using a later ABI. In the case of an ABI break, if you receive a linker error, you can consider yourself lucky. In some cases, such as mixing NDEBUG code with debug code, you'll likely get memory corruption if a class only has members available in one such configuration' for instance, special members being added for better debugging.
Some memory corruptions, which are often hard to debug, can easily be turned into linker errors with the use of C++11's inline namespaces...