Happily linking incompatible types leads to chaos

穿精又带淫゛_ 提交于 2019-12-05 14:37:44

In your example, you could put the definition of Y in an anonymous namespace like this:

#define TMPL_Y(name,T) \
namespace { \
    struct Y { \
      T y; \
      void f() { \
        std::cout << name << "::f " << y << std::endl; \
      } \
      virtual void vf() { \
        std::cout << name << "::vf " << y << std::endl; \
      } \
      Y() { \
        std::cout << name << " ctor" << std::endl; \
      } \
      ~Y() { \
        std::cout << name << " dtor" << std::endl; \
      } \
    }; \
}

this essentially creates a unique namespace for each compilation unit and you have, in effect, unique Y's, and the linker will be able to associate correctly.

As for the statement

za.y = zb.y;

this will still yield unpredictable results of course as the 2 types are incompatible.

Quoting Bjarne Stroustrup's "The C++ Programming Language":

9.2 Linkage

Names of functions, classes, templates, variables, namespaces, enumerations and enumerators must be used consistently across all translation units unless they are explicitly specified to be local.

It is the programmer's task to ensure that every namespace, class, function, etc. is properly declared in every translation unit in which it appears and that all declarations referring to the same entity are consistent. [...]

In many cases there are errors that the C++ compiler is not required to catch. Many of them are for example errors that are impossible to detect by analyzing one translation unit at a time.

For example without making complex cases with templates if you just declare in an header file

void foo(int x);

and then you provide two distinct definitions for the function in different translation units the C++ compiler is not required to give an error at link time.

Note that this is clearly not impossible to happen by mistake because indeed there could even be two distinct headers with a global function with the same signature and part of the project using one header and part of the project using the other.

The same can happen if you declare a certain class Foo in two different header files with different declarations and with different implementations.

This abuse of naming is simply a kind of error that the compiler is not required to be able to catch.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!