Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.08.2012, 15:27   #1
MrGukk
Пользователь
 
Регистрация: 09.05.2011
Сообщений: 33
По умолчанию Инициализация структур с перечислениями

Здравствуйте,

Столкнулся с ситуацией ниже:
Код:
typedef enum
{
    RED = 1,
    GREEN,
    BLUE,
    GLUE
} Color;

typedef struct
{ 
    Color color;
    int a;
    double d;
}   MStruct;

int _tmain(int argc, _TCHAR* argv[])
{   
    MStruct mstruct = {0};
}
При попытке инициализации структуры "нулями" возвращается ошибка компилятора:
error C2440: 'initializing' : cannot convert from 'int' to 'Color'
1> Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)

С другой стороны если поменять порядок полей в MStruct так:
Код:
typedef struct
{
    int a;
    double d;
    Color color;
}   MStruct;
То никаких ошибок не возникает и код работает нормально.
Не могли бы вы пояснить почему так происходит или кинуть ссылки где можно почитать.

Вопрос сюда же.
Можно ли инициализировать структуру "нулями" если она вся состоит из перечислений?

Заранее спасибо.
MrGukk вне форума Ответить с цитированием
Старый 06.08.2012, 15:35   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
почему так происходит
Может быть и тут срабатывает знаменитая характерность компиляторов определять тип по первому элементу?
Я лично предпочел бы использовать ZeroMemory для инициализации. Ему по боку какого типа поля.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.08.2012, 15:40   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

потому что указав лишь одно значение, вы указываете значение первого поля структуры, в первом случае оно Color, что компиль и говорит.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.08.2012, 16:09   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2MrGukk
Цитата:
MStruct mstruct = {0};
ты попросил компилятора инициализировать первое поле нулем, остальные поля при этом так же проинициализируются нулем автоматически. в крестах неявное приведение int к enum запрещено, поэтому и ошибка. если же ты переносишь enum поле, то компиль автоматически кастует int к enum. кстати в сях такого правила нет, соответственно и ошибки такой тож
c++ http://ideone.com/3Rw3n
c http://ideone.com/CONmk
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 06.08.2012 в 16:14.
pproger вне форума Ответить с цитированием
Старый 06.08.2012, 20:02   #5
MrGukk
Пользователь
 
Регистрация: 09.05.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Может быть и тут срабатывает знаменитая характерность компиляторов определять тип по первому элементу?
Я лично предпочел бы использовать ZeroMemory для инициализации. Ему по боку какого типа поля.
Zero Memory - макрос определённый в windows.h, так что портировать на линукс в чистом виде не получится.

Цитата:
Сообщение от pproger Посмотреть сообщение
2MrGukk

ты попросил компилятора инициализировать первое поле нулем, остальные поля при этом так же проинициализируются нулем автоматически. в крестах неявное приведение int к enum запрещено, поэтому и ошибка. если же ты переносишь enum поле, то компиль автоматически кастует int к enum. кстати в сях такого правила нет, соответственно и ошибки такой тож
c++ http://ideone.com/3Rw3n
c http://ideone.com/CONmk
За это спасибо.

Есть ли выход, если нужно определить структуру с 2-мя перечислениями и инициализировать её или всё-же нужно инициализировать все поля по-порядку?

Последний раз редактировалось Stilet; 06.08.2012 в 20:20.
MrGukk вне форума Ответить с цитированием
Старый 06.08.2012, 20:05   #6
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2MrGukk
Цитата:
Zero Memory - макрос определённый в windows.h, так что портировать на линукс в чистом виде не получится.
это просто синоним для memset(..., 0, ...)
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 06.08.2012, 20:07   #7
MrGukk
Пользователь
 
Регистрация: 09.05.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от MrGukk Посмотреть сообщение
Zero Memory - макрос определённый в windows.h, так что портировать на линукс в чистом виде не получится.
Хотелось бы что-то более универсальное.
MrGukk вне форума Ответить с цитированием
Старый 06.08.2012, 20:09   #8
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2MrGukk
Цитата:
Есть ли выход, если нужно определить структуру с 2-мя перечислениями и инициализировать её или всё-же нужно инициализировать все поля по-порядку?
1. если перечисления в начале структуры - инициализируй их, остальное автоматом нулями заполнится.
2. если в рандомном порядке - инициализировать надо все члены вплоть до последнего перечисления.
3. если использовать современный С (а не кресты), то
Код:
struct mystruct {
    int a;
    Color b;
    char c;
    Color d;
};

...

struct mystruct s = {
    .b = RED,
    .d = BLACK
};
если кресты - инициализируй в конструкторе так, как тебе надо
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 06.08.2012, 20:13   #9
MrGukk
Пользователь
 
Регистрация: 09.05.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2MrGukk


это просто синоним для memset(..., 0, ...)
Пробовал. memset выдает такую же ошибку.
MrGukk вне форума Ответить с цитированием
Старый 06.08.2012, 20:16   #10
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2MrGukk
Цитата:
Пробовал. memset выдает такую же ошибку.
http://ideone.com/bmf5S
где?

прошу заметить, что хотя код и коНпелируется, ошибка присутствует, ибо полю color установилось недопустимое для него значение (0), т.к у тебя enum с единицы. т.е это нужно отлавливать перед использованием переменной
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
инициализация из файла CodeNOT Общие вопросы C/C++ 0 18.12.2010 20:32
Инициализация Aleksey1989 Общие вопросы Delphi 10 11.09.2010 21:50
Инициализация Krumyura Общие вопросы C/C++ 5 20.03.2010 23:37
Инициализация DirectX Pedro Gamedev - cоздание игр: Unity, OpenGL, DirectX 2 30.09.2009 21:06
[C++] Инициализация массива структур отдельно от объявления MariyaL Помощь студентам 0 30.09.2009 12:27