C++’s One Definition Rule (ODR) can cause subtle and hard-to-detect issues when compile-time switches lead to inconsistent definitions across translation units. However, by using type aliases and template instantiation, we can sidestep these violations—giving each module its own definition without triggering undefined behavior.
Using C++ Type Aliasing to Avoid the ODR Problem with Conditional Compilation, Part 1
by Raymond Chen
From the article:
Some time ago, I discussed the C++ concept of ill-formed no diagnostic required (IFNDR). A common accidental source of this is violating the One Definition Rule (ODR) by defining a class or function differently based on compile-time switches.
// widget.h struct Widget { Widget(); void SetName(std::string const& name); ⟦ more stuff ⟧ #ifdef EXTRA_WIDGET_DEBUGGING Logger m_logger; void Log(std::string const& message) { m_logger.log(message); } #else void Log(std::string const& message) { // no extra logging } #endif std::string m_name; };If one .cpp file is compiled with extra widget debugging enabled, but another is compiled with extra widget debugging disabled, and they are linked together, then you have a One Definition Rule violation because the
Widget
structure and theWidget::Log
method have conflicting definitions.But all is not lost.
Add a Comment
Comments are closed.