Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link compatibility of enums and enum classes

Suppose there is a C++11 API that uses enum classes:

// api.hpp
enum class E {A, B, C};
void f(E);
...

// api.cpp
void f(E e)
{
    if (e == E::A)
       ...
}

Now suppose I would like to use this API, but I don't have a C++11 compiler. So I:

  • Modify api.hpp and change the enum class to be just a regular enum.
  • Write some code code that includes the modified api.hpp and uses the API normally (e.g. calls f).
  • Compile this code with my non-C++11 compiler and link it to the API implementation which was compiled with a C++11 compiler (using the unmodified api.hpp).

This seems to work with GCC, but is it safe in general, or am I playing with fire (ODR violations and such)?

Assume the two compilers are otherwise link-compatible, it is only the enum vs. enum class that is at issue.

like image 839
HighCommander4 Avatar asked Apr 28 '12 07:04

HighCommander4


2 Answers

Like ildjarn is saying, this is undefined behavior. And the reason that this actually can fail on real implementations is that normal C++03 enums don't have a fixed underlying type. While your enum-class type always has "int" as its underlying type, a corresponding C++03 enum could have "short" as its underlying type, making the code not be layout compatible.

like image 162
Johannes Schaub - litb Avatar answered Nov 19 '22 08:11

Johannes Schaub - litb


You would be violating the One Definition Rule (§3.2/5). Result: undefined behavior.

like image 42
ildjarn Avatar answered Nov 19 '22 06:11

ildjarn