Abu-Corinne, Villain-Marais, заядлый стоматолог ([info]henic) wrote,
  • Music: Los_Del_Rio-Macarena
Нужна скорая помощь по C. Бо меня на гугле забанили заклинило.

Есть два типа enum. Кое-где в программе переменные одного из типов сравниваются с константами другого. Компилятор жрет без проблем, видимо, потому что считает их int, не заморачиваясь. А мне надо отловить эти ошибочные сравнения на этапе компиляции. Что бы подкрутить? Как-то уломать компилятор делать strict проверки типов?

Upd: Компилятор - под Visual Studio.

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    Your reply will be screened

    Your IP address will be recorded 

  • 32 comments

[info]trurle

December 14 2009, 16:26:32 UTC 2 years ago

gcc -Wenum-compare?

[info]henic

December 14 2009, 16:30:21 UTC 2 years ago

Сорри, забыл сказать. Visual studio. :(

[info]mopexod

December 14 2009, 16:39:54 UTC 2 years ago

Думаю, что по-простому - никак, к strict проверкам типов это отношения не имеет.
Но с интересом почитаю ответы, а вдруг и прада - можно? :)

[info]henic

December 14 2009, 16:42:27 UTC 2 years ago

Похоже, что легче будет проверить двести вхождений вручную. :(

[info]ygam

December 14 2009, 16:42:30 UTC 2 years ago

Что-то навроде этого:

#ifdef DEBUG

class Enum1
{
private:
int _v;
Enum1(int v) : _v(v) {}
public:
static Enum1 V1() { Enum1 e(0); return e; }
static Enum1 V2() { Enum1 e(1); return e; }
static bool operator == (const Enum1 &other) { return _v == other._v; }
};
#else

enum Enum1 {V1,V2};

#endif

[info]henic

December 14 2009, 16:43:53 UTC 2 years ago

Cпасибо!

[info]ygam

December 14 2009, 16:44:13 UTC 2 years ago Edited:  December 14 2009, 16:44:52 UTC

Не совсем; 3 года не программировал на сиплюсплюсе.

Внутри определения класса:

static Enum1 V1;
static Enum1 V2;

Вне определения класса:

Enum1 Enum1::V1 (0);
Enum1 Enum1::V2 (1);

[info]henic

December 14 2009, 16:45:36 UTC 2 years ago

Спасибо еще раз. Я понял идею, дальше уже напильником обработаю, если что-то не будет работать.

[info]trurle

2 years ago

[info]henic

2 years ago

[info]mfi

2 years ago

[info]mopexod

December 14 2009, 18:05:06 UTC 2 years ago

Я прямо сейчас не могу проверить, но, кажется, Enum1::V1 для настоящих enums не валидно в С++. То есть обращение к V1, V2 будет разным в дебаг и релиз.

[info]ygam

2 years ago

[info]gct

December 14 2009, 19:42:13 UTC 2 years ago

не понимаю в этой теме :(

[info]henic

December 14 2009, 19:50:47 UTC 2 years ago

Ничего страшного. :) Примерный ход подсказали, завтра разберусь.

[info]vicnick

December 14 2009, 21:39:43 UTC 2 years ago

// Проверял на Visual Studio 2008
enum Enum1
{
E1 = 1
};
enum Enum2
{
E2 = 2
};
void test()
{
Enum1 e1;
e1 = E1; // ok
e1 = (Enum1)E2; // ok
e1 = E2; // error C2440: '=' : cannot convert from 'Enum2' to 'Enum1'
}
// Проверить в среде Visual Studio 2005 не могу.

[info]mopexod

December 15 2009, 01:09:14 UTC 2 years ago

Не присваивания, а сравнения. Присваивание - не вопрос :)

[info]henic

December 15 2009, 06:19:43 UTC 2 years ago

Спасибо. Вообще странно, потому что не вижу, чем отличается от используемого мной.

[info]ozlev

December 15 2009, 06:49:53 UTC 2 years ago

А почему тебя в Гугле забанили? Требую толкования идиомы со ссылками...

[info]henic

December 15 2009, 06:54:33 UTC 2 years ago

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

[info]ozlev

December 15 2009, 07:03:30 UTC 2 years ago

Разленился...
Я тут три дня форумы шерстил в поисках магической формулы...

[info]henic

December 15 2009, 07:04:11 UTC 2 years ago

Нет смысла. Даже двести вхождений - проще вручную глянуть.

[info]yba

December 16 2009, 11:42:41 UTC 2 years ago Edited:  December 16 2009, 11:44:28 UTC

если еще не сделал такой вариант работает:
enum    E1 
{ 
    V1, 
    V2 
}; 

enum    E2 
{ 
    V3, 
    V4 
}; 

template    <typename    T1,    typename    T2>
bool    operator==(T1 t1,T2 t2)
{ 
    float a = "asd"; 
} 

template    <typename    T1,    typename    T2>
bool    operator!=(T1 t1,T2 t2)
{ 
    float a = "asd"; 
} 

int    main() 
{ 
    E1    e1=V1; 
    E2    e2=V3; 
     
    if    (e1==V2) 
        std::cout<<"+\n";
    if    (e1==V3) 
        std::cout<<"-\n"; 
    if    (e1!=e2) 
        std::cout<<"-\n"; 
    if    (e2==V4) 
        std::cout<<"+\n";
    if    (e2!=V2) 
        std::cout<<"-\n"; 
    if    (e2==e1) 
        std::cout<<"-\n"; 
         
    return 0; 
} 


в строках где разнотипное сравнение VS2003 дает ошибку типа
main.cpp(235) : error C2440: 'initializing' : cannot convert from 'const char [4]' to 'float'
There is no context in which this conversion is possible
main.cpp(251) : see reference to function template instantiation 'bool operator !=<E2,E1>(T1,T2)' being compiled
with
[
T1=E2,
T2=E1
]

болдовая строка - как раз место сравнения
Если же разнотипных сравнений уже нет - все будет компилироваться без ошибок

[info]henic

December 16 2009, 11:50:59 UTC 2 years ago

Спасибо!

[info]henic

December 16 2009, 16:45:32 UTC 2 years ago

Оппа... Какой паровоз других не совсем корректных сравнений эта штука мне нашла. :) Большое человеческое спасибо. ))))

[info]vicnick

December 16 2009, 21:35:22 UTC 2 years ago

Очень красивое решение :)

[info]Ex 314truha [myopenid.com]

March 3 2010, 19:38:22 UTC 2 years ago

Так это мне теперь что же, unsigned int с DWORD теперь сравнить нельзя? Я уж молчу про wchar_t с short ...

[info]henic

March 3 2010, 21:38:17 UTC 2 years ago

А нехер! :)
За двадцать лет ни разу не случилось работать с wchar.

[info]yba

March 4 2010, 10:43:02 UTC 2 years ago

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

[info]henic

2 years ago

Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…