Обнаружение определений с одинаковым именем enum и #define в исходном коде C++

У нас есть исходный код C++ с большим количеством определений, сделанных с использованием #define и enum. Недавно при анализе ошибки мы обнаружили, что было несколько определений, сделанных с использованием директивы препроцессора #define, которые также были членами перечисления. Однако значения, присвоенные им, были разными.

Например,

#define ABC 100

typedef enum
{
  ABC = 1,
  DEF
} MY_ENUM;

ABC определяется в двух местах.

Удивительно, но Visual Studio не выдала нам ошибку. Даже не предупреждение.

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

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

Кто-нибудь знает способ обнаружить эти множественные определения?

Мы используем Visual Studio 2010 Professional в качестве IDE.


person Anusha Dharmasena    schedule 10.11.2015    source источник
comment
Вот почему вы не должны использовать заглавные буквы ни для чего, кроме макросов.   -  person emlai    schedule 10.11.2015
comment
Похоже, это хороший момент, чтобы провести день уборки. Замените #define на const int ABC = 100;, и Visual Studio будет жаловаться.   -  person MSalters    schedule 10.11.2015


Ответы (2)


Используйте enum class вместо enum. Таким образом, вы можете быть уверены, что используете нужную вещь в нужном месте.

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

ПРИМЕЧАНИЕ. enum class — это функция C++11, которая не поддерживается Visual Studio 2010.

person The Apache    schedule 10.11.2015
comment
Спасибо. Несмотря на то, что я не могу использовать его, если VS2010 его поддерживает, я бы помнил об этом. Я не знал о классе enum. - person Anusha Dharmasena; 18.11.2015
comment
Если это решает вашу задачу, пожалуйста, отметьте это как правильное. - person The Apache; 18.11.2015

Даже VS не скомпилирует код, который вы показали. Но он мог бы делать то, что вы описываете, если бы #define шло после определения enum. И если это так, все компиляторы будут делать именно то, что вы описываете. Тогда код никоим образом не является недействительным (или даже заслуживающим предупреждения).

Как предлагает @TheApache, решением C++11 будет использование enum class вместо простого enum, но это будет требуют, чтобы вы прошли все варианты использования и добавили квалификацию. Не говоря уже о том, что Visual Studio 2010 его не поддерживает.

Использование макроса и одноименного перечислителя в проекте — крайне плохая идея, поэтому вам определенно следует разрешить ситуацию, удалив это условие. В идеале вы должны просто удалить определения макросов и использовать только перечислители.

person Angew is no longer proud of SO    schedule 10.11.2015
comment
Спасибо, но если VS2010 его не поддерживает, я не могу его использовать. - person Anusha Dharmasena; 18.11.2015
comment
@nushydude Что, я думаю, вы должны сделать (и что говорит ответ), так это просто полностью избавиться от макросов. - person Angew is no longer proud of SO; 18.11.2015