Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> приведение int к enum 
:(
    Опции темы
itan
Дата 12.12.2006, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 3.7.2006

Репутация: нет
Всего: нет



Вот есть у меня свой тип данных :
Код

enum Type {Type1 = 10, Type2 = 20, Type3 = 30 };

и есть функция, которая принимает этот тип в качестве параметра:
Код

void func(Type t)
{
    Type tNew = t;
         ...

}

Вопрос в том - как мне можно защитить функцию func от передачи ей значений не свойственных типу Type , например таким образом:
Код

func(static_cast<Type>(45))

Для усложнения задачи предположим, что количество "типов" у Type может быть большим и разброс их значений существеннен.
PM MAIL   Вверх
Anikmar
Дата 12.12.2006, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Она уже защищена.
При попытке вызвать функцию с параметром int будет выдано предупреждение компилятора (или ошибка, не помню точно) о несовпадении параметров или о неявном преобразовании
т.е. чтобы компилилось без проблем нельзя будет писать
func(0);
Надо будет писать
func(Type1)
PM MAIL ICQ   Вверх
JackYF
Дата 12.12.2006, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Anikmar @  12.12.2006,  14:17 Найти цитируемый пост)
предупреждение 


Именно, что предупреждение. Тут этого ИМХО недостаточно.

Программист при желании сможет передать в функцию любое целое число.
Так что фильтровать, так или иначе, придется.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Anikmar
Дата 12.12.2006, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Си чем и хорош - тут программист может творить практически все что угодно - на то он и программист, чтобы следить за собой.

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

Чтобы полностью защищать функции - лучше работать на паскале. В Си с помощью преобразования типов - такого можно наворотить... Никакими защитами не избежать.

Вообще-то я слышал о дуракоустойчивости программ по отношению к пользователям, а вот чтобы она дуракоустойчивая по отношению к программистам была...

В конце концов одну проверку в функцию поставить не так уж и сложно.
PM MAIL ICQ   Вверх
Fazil6
Дата 12.12.2006, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

Чтобы полностью защищать функции - лучше работать на паскале.

ерунда. Лучше - это вообще ничего не делать.

А вообще int автоматом не приводится к enum, а если вы взламывать будете static_cast-ом или reinterpret , то что же вы хотели?

Не лгите компиллятору , иначе он будет мстить.





Это сообщение отредактировал(а) Fazil6 - 12.12.2006, 14:51
PM MAIL   Вверх
Anikmar
Дата 12.12.2006, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Цитата(Fazil6 @ 12.12.2006,  14:50)
ерунда. Лучше - это вообще ничего не делать.

Целиком и полностью с этим согласен.
PM MAIL ICQ   Вверх
UnrealMan
Дата 12.12.2006, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(JackYF @  12.12.2006,  14:33 Найти цитируемый пост)
Именно, что предупреждение. 

Стандарт не разрешает неявное преобразование целого в перечисление. Нормальный компилятор должен выдать ошибку.
PM MAIL   Вверх
JackYF
Дата 12.12.2006, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(UnrealMan @  12.12.2006,  15:30 Найти цитируемый пост)
неявное


А явное?



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 12.12.2006, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(JackYF @  12.12.2006,  15:38 Найти цитируемый пост)
А явное?

Явное разрешено:

Цитата(ISO/IEC 14882:2003(E) §7.2 Enumeration declarations)
An expression of arithmetic or enumeration type can be converted to an enumeration type explicitly. The value is unchanged if it is in the range of enumeration values of the enumeration type; otherwise the resulting enumeration value is unspecified.

PM MAIL   Вверх
Anikmar
Дата 12.12.2006, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



C++ Builder никаких проверок не делает. Выдает предупреждение: инициализация нумератора целым числом.

Вывод:
C++ Builder НЕНОРМАЛЬНЫЙ компилятор!  smile 

Но если серьезно, нормальный программер на Си должен обязательно поглядывать на предупреждения, за некоторыми из них - 100% ошибка, например "Возможно некорректное присваивание" - по запаре забыл второе равно воткнуть в условие и т.п.

Так что все равно смотреть надо, что пишешь.

Если программер сам ручками пишет некое преобразование (MyEnumType)99999 - то ему и флаг в руки!
PM MAIL ICQ   Вверх
maxim1000
Дата 12.12.2006, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



где-то встречал такой подход:
вместо enum делается класс
конструкторы прячутся (только копирования оставляют)
зато делают несколько функций типа
Код

CMonth January()
{
    static CMonth january(1);
    return january;
}

и пользуются в программе значениями January(), February(), ...
а static_cast in в класс, по-моему, даёт ошибку...


--------------------
qqq
PM WWW   Вверх
JackYF
Дата 12.12.2006, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Программер, пишущий код, должен максимально защитить свой код от неправильных входных параметров.
Объявлять, что параметр должен передаваться только так и никак иначе - это не выход.

Гораздо безопаснее все-таки внутри функции отсеивать неправильные значения.

Цитата(Anikmar @  12.12.2006,  16:08 Найти цитируемый пост)
Если программер сам ручками пишет некое преобразование (MyEnumType)99999 - то ему и флаг в руки! 


Писать код желательно с расчетом на то, что результирующий программист будет делать с приведенным интерфейсом что угодно.
ИМХО пиши проверки. Хотя бы в дебаг-версии..., или с какой-нибудь другой условной компиляцией...



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
UnrealMan
Дата 12.12.2006, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Anikmar @  12.12.2006,  16:08 Найти цитируемый пост)
Вывод:
C++ Builder НЕНОРМАЛЬНЫЙ компилятор!  

Именно так! Всё, что не разрешено стандартом, запрещено. Разработчик компилятора не вправе пороть отсебятину, в частности – расширять множество неявных преобразований, перечисленных в стандарте C++ (а возможность неявного преобразования целого в перечисление там нигде не указана).

Например, если мы сделаем перегрузку:

Код
enum En { en_val = 1 };
void Func(...) { cout<<"..."<<endl; }
void Func(En) { cout<<"En"<<endl; }

при вызове Func(1) по стандарту обязана вызваться функция с эллипсисом. А ежели в программе, сгенеренной компилятором, вызывается вторая функция (и компилятор ещё смеет сыпать тут своими дурацкими предупреждениями – мол, посмотрите, какие умные вам разработчики компилятора попались: авторы стандарта им в подмётки не годятся), то место такому компилятору в топке.
PM MAIL   Вверх
JackYF
Дата 12.12.2006, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(UnrealMan @  12.12.2006,  16:57 Найти цитируемый пост)
Разработчик компилятора не вправе пороть отсебятину


Так-то оно так, но:

1) как минимум разработчики компиляторов GCC, MSVC, BCC порят отсебятину (каждый свою).
2) во всех этих компиляторах возможно включение опции типа "Ansi компиляция", которая отменяет все эти самые навороты и перевороты.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Anikmar
Дата 12.12.2006, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



На счет приведенного примера перегрузки (оставляю свое мнение на подобный код при себе) - мне стало интересно. В Билдере срабатывает функция (...)

Хотя я ожидал, что комп запутается. 

PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0927 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.