2012-04-28 6 views
6

Предположит, есть C++ 11 API, который использует перечисления классов:Связи перечислений и перечисления классов

// 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 vs. enum.

ответ

5

Как ildjarn говорит, это неопределенное поведение. И причина, по которой это действительно может произойти при реальных реализациях, заключается в том, что обычные C++ 03 перечисления не имеют фиксированного базового типа. Хотя ваш тип перечисления типа всегда имеет «int» в качестве его базового типа, соответствующий переписчик C++ 03 может иметь «короткий» в качестве базового типа, делая код не совместимым с макетом.