Совместимость ссылок перечислений и классов перечислений

Предположим, что существует API C++11, использующий классы enum:

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

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

Теперь предположим, что я хотел бы использовать этот API, но у меня нет компилятора C++11. Так что я:

  • Измените api.hpp и измените класс перечисления, чтобы он был обычным перечислением.
  • Напишите некоторый код, который включает измененный api.hpp и нормально использует API (например, вызывает f).
  • Скомпилируйте этот код с помощью моего компилятора, отличного от C++11, и свяжите его с реализацией API, которая была скомпилирована с помощью компилятора C++11 (используя немодифицированный api.hpp).

Кажется, это работает с GCC, но безопасно ли это в целом, или я играю с огнем (нарушения ODR и тому подобное)?

Предположим, что два компилятора в остальном совместимы по ссылкам, проблема заключается только в классе enum и enum.


person HighCommander4    schedule 28.04.2012    source источник


Ответы (2)


Как говорит Ильджарн, это поведение undefined. И причина того, что это на самом деле может дать сбой в реальных реализациях, заключается в том, что обычные перечисления С++ 03 не имеют фиксированного базового типа. В то время как ваш тип класса enum всегда имеет "int" в качестве базового типа, соответствующее перечисление C++03 может иметь "short" в качестве базового типа, что делает код несовместимым с компоновкой.

person Johannes Schaub - litb    schedule 28.04.2012

Вы нарушите правило одного определения (§3.2/5). Результат: неопределенное поведение.

person ildjarn    schedule 28.04.2012