Почему я не могу присвоить правильное значение переменной типа Enum C ++?

StackOverflow https://stackoverflow.com/questions/19835143

Вопрос

Я не могу понять, что там происходит. Используя Visual Studio 2008, я определил перечисление, как это:

enum MyType{
    A,
    B,
    C
};

Затем я использую его для инициализации переменной члена:

class MyClass
{
    private:
        bool   bit_;
        uint16 num_;
        MyType member_;
    public:
        MyClass(MyType value){
            member_ = value; // This the assignment which fails
        } // Here, there's a breakpoint to query member_ value    
};

Myclass ancess = new myclass ();

Я использую конфигурацию отладки, поэтому никакая оптимизация не может обмануть меня при чтении переменной. В точке перерыва сразу после назначения отладчик показывает значение member_ как member_ = C.

Это может быть отладчик, выпуская обновление, но внутри метода он оценивает истину при проверке:

if(member_ == C){
    // ??
}

А также, назначение другим значениям дает странные числа, например member_ = B дает member_ = 258 Когда он разбирается. Вы можете сказать мне, что случилось? Заранее спасибо.

РЕДАКТИРОВАТЬ #1

Я отметил забавный эффект, который объясняет, почему после назначения member_ = A выражение member_ == C оценивает true Для перечисления со значениями по умолчанию:

Для перевода

enum MyType{ A, B, C}; // equivalent to enum MyType{ A = 0, B = 1, C = 2};

я получил

MyType  a = A; // but when fetching a the value is   2  (0x0002)  thats the map for C!
MyType  b = B; // but when fetching a the value is 258  (0x0102)
MyType  c = C; // but when fetching a the value is 514  (0x0202)

Но если я сделаю

enum MyType{ A = 5, B = 6, C = 7};

я получил

MyType  a = A; // but when fetching a the value is 1282  (0x0502)
MyType  b = B; // but when fetching a the value is 1538  (0x0602)
MyType  c = C; // but when fetching a the value is 1794  (0x0702)

Итак, при назначении этого #?!^% Enum, правило, кажется, сдвиньте 8 бит и добавьте 2. Это звучит как проблемы компилятора.

Кстати, создавая тип member_ быть int вместо MyType ничего не меняет.

РЕДАКТИРОВАТЬ #2Добавили еще два члена в класс, которые являются реальной причиной проблемы. Я опубликую ответ, как только ограничение времени исчезнет (8 часов от публикации вопроса).

Это было полезно?

Решение 2

Спасибо всем. Кто -то на работе указал мне на происхождение проблемы.

Это вопрос неправильной конфигурации проекта, которая дает проблемы выравнивания данных.

После компиляции, с текущими настройками проекта, два первых члена класса имеют 3 байта размера.

Это должно быть 4 байта, следовательно, смещение 1 байта. Дополнительное 2 добавлено мусор в смещенном байте, поэтому весь эффект состоит в том, чтобы сдвинуть один байт и добавить 2.

Этот эффект отменяется, добавляя дополнительный член, хотя это не элегантное решение (решение состоит в том, чтобы настроить проект, соответственно).

class MyClass
{
    private:
        bool   bit_;  // 1 byte
        uint16 num_;  // 2 byte

        bool dummy;   // extra byte to help the alignment

        MyType member_;
    public:
        MyClass(MyType value){
            member_ = value; // Now it works as expected.
        }
};

Другие советы

Записи Enum не обязательно должны иметь уникальные значения. У вас может быть перечисление с A, B, C, где как A, так и C равны «42». В таком случае, когда VAR имеет значение 42, IDE покажет вам только один соответствующих записей, A или C, не оба.

Вы можете легко создать перечисление с «дублирующими» записями, например:

enum { A=1, B=1, C=1 }

Но, скорее всего, вы этого не делали. Однако при использовании аутоплеменции вы можете случайно (или намеренно) создать дубликаты:

enum { A, B, C }       // 0,1,2
enum { A, B, C=0 }     // 0,1,0
enum { A=2, B=1, C }   // 2,1,2
enum { A=-1, B, C=0 }  // -1,0,0

Обязательно проверьте свое определение перечисления.

Смотрите т.е. http://www.learncpp.com/cpp-tutorial/45-enumerated-types/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top