cppcheck считает, что у меня избыточный код: найден оператор, начинающийся с числовой константы

Cppcheck (версия 1.46.1) выдает следующее предупреждение для перечисления как этот:

enum DATABASE_TYPE
{
    DATABASE_TYPE_UNKNOWN = -1, // <- line of warning
    DATABASE_TYPE_ORACLE,
    DATABASE_TYPE_MSACCESS
};

Избыточный код: найден оператор, начинающийся с числовой константы.

Не думаю, что это лишнее. Очень важно уметь делать такие вещи.

Это ошибка cppcheck или я чего-то не вижу?

Обновлять

Мне удалось свести это к минимальному примеру. Это было осложнено тем, что cppcheck имел 2 (дополнительные) ошибки, из-за которых казалось, что мои сокращения не имели никакого эффекта.
Есть 5 файлов: a.h, a.cpp, b.h, b.cpp и inc.h со следующим содержимым.
VC9 компилирует его. без предупреждений (уровень предупреждения 4).

// a.h
#pragma once
#include "inc.h"

// a.cpp
#include "a.h"
#include "b.h"

int main()
{
    return 0;
}


// b.h
#pragma once
#include "inc.h"

// b.cpp
#include "b.h"

//inc.h
#pragma once

enum MY_ENUM_TYPE
{
    INVALID_VALUE = -1,
    FIRST_VALUE,
    SECOND_VALUE
};

Так что к настоящему времени я почти уверен, что это ошибка cppcheck. Есть расходящиеся мнения?


person foraidt    schedule 02.02.2011    source источник
comment
Да, это похоже на ошибку cppcheck — #pragma Once не работает. Если вы замените его на перенос заголовков #ifndef A_H / #define A_H / #endif, cppcheck больше не будет жаловаться.   -  person Johan Kotlinski    schedule 02.02.2011
comment
Это также похоже на признанную проблему: sourceforge.net/apps/trac/cppcheck/ticket/ 2417   -  person Johan Kotlinski    schedule 02.02.2011
comment
@kotlinksi: Если бы вы обновили свой ответ этим, я мог бы пометить его как принятый.   -  person foraidt    schedule 02.02.2011


Ответы (2)


Я предполагаю, либо:

A) invalid каким-то образом объявлено или определено в другом месте.

B) перечисление определено в заголовке, включенном дважды (без защиты заголовка). Потому что вы получаете ту же ошибку для этого кода:

enum SomeEnumType
{
    invalid = -1,
    first,
    second,
};

enum SomeEnumType
{
    invalid = -1, // <- line of warning
    first,
    second,
};

Ваш код компилируется с помощью GCC?


ОБНОВИТЬ:

Да, это похоже на ошибку cppcheck - #pragma once не работает. Если вы замените его на обтекание заголовков #ifndef A_H/#define A_H/#endif, cppcheck больше не жалуется.

Это также похоже на известную проблему.

person Johan Kotlinski    schedule 02.02.2011
comment
invalid это просто пример. На самом деле он больше похож на invalidSomeEnumType, так что он довольно уникален. - person foraidt; 02.02.2011
comment
@foraidt: Это действительно пустая трата времени, чтобы задавать вопросы о поддельном коде. Опубликуйте настоящий код, чтобы мы могли решить настоящие проблемы. - person GManNickG; 02.02.2011
comment
@foraidt: Попробуйте создать минимальный пример, который выдаст ошибку, тогда будет ясно, в чем проблема. В любом случае, проблема не в том, что вы присваиваете ему значение -1, проблема в том, что cppcheck считает, что invalid уже определено. Если вы обнаружите ошибку в cppcheck, сообщите об этом разработчикам, они ее быстро исправят. - person Johan Kotlinski; 02.02.2011
comment
@GMan: он обновлен. Но я сомневаюсь, что сейчас от него больше пользы. Все еще нельзя сказать, определена ли недопустимая часть многократно, без проверки всей кодовой базы. - person foraidt; 02.02.2011
comment
@kotlinksi: я попытался создать минимальный пример, но не смог изолировать проблему. И поскольку код, кажется, компилируется и работает нормально, именно поэтому я спросил об этом здесь. - person foraidt; 02.02.2011
comment
@foraidt: Намного лучше. :) Две вещи, однако, во-первых, как человек, задающий вопрос, вы, как правило, наименее квалифицированы, чтобы знать, какая информация нужна, потому что, если бы вы точно знали, какая информация нужна, вы бы решили ее самостоятельно. :) Тем не менее, во-вторых, речь идет не о реальном коде, который определенно имеет значение, а о поддельном коде, который может иметь значение, и мы хотим, чтобы это было неправдой. - person GManNickG; 02.02.2011
comment
@foraidt: Самый простой способ сделать это — просто взять проверяемый файл .cpp и удалить все строки, которые не нужны для получения ошибки. Затем просмотрите все включенные файлы .h, удалите все строки, которые не вызывают проблемы. В конце концов у вас будет очень небольшая коллекция минимальных файлов .cpp и .h. - person Johan Kotlinski; 02.02.2011

перечисления имеют тип данных как целые числа без знака.

Обновление: похоже, что это определено реализацией: перечисления С++ подписаны или не подписаны?

person Arunmu    schedule 02.02.2011
comment
Неправда: stackoverflow.com/questions/159034 / - person Johan Kotlinski; 02.02.2011
comment
@Kotlinski: Это ссылка, которую я указал в качестве обновления моего ответа. И голосование против, и снова указание на ту же ссылку, которую я дал. Принятый ответ четко говорит: :: Кроме того, в стандарте говорится, что реализация определяет, какой целочисленный тип используется в качестве базового типа для перечисления, за исключением того, что он не должен быть больше, чем int, если только какое-то значение не может поместиться в int или a беззнаковый внутр. - person Arunmu; 02.02.2011
comment
@ArunMu: разместил комментарий до того, как увидел ваше обновление. В любом случае, на самом деле не имеет значения, является ли базовая реализация int или unsigned int, если только вы не сравните с ‹ или ›. - person Johan Kotlinski; 02.02.2011
comment
@Kotlinski:: Как ты можешь такое говорить?? Если реализация идет с беззнаковым целым числом, как вы думаете, она примет отрицательное значение как отрицательное значение? (если конечно не кастинг) - person Arunmu; 02.02.2011
comment
@ArunMu: unsigned int i = -1; преобразуется в 0xffffffffu. По крайней мере, на gcc это работает нормально, даже с самыми высокими уровнями предупреждений. Представление действительно такое же... - person Johan Kotlinski; 02.02.2011
comment
@kotlinski: я действительно не против понизить голос :) но почему-то я не доволен ответами. - person Arunmu; 02.02.2011
comment
Цитата: Базовый тип перечисления — это целочисленный тип, который может представлять все значения перечислителя, определенные в перечислении. Таким образом, ответ не актуален и по-прежнему начинается с неправильного утверждения, поэтому отрицательный голос. - person Georg Fritzsche; 02.02.2011