2013-08-30 2 views
2

Рассмотрите следующее объявление функции и определение. В заголовочном файле:Предупреждение C4028 Visual Studio (формальный параметр отличается от декларации) ложным?

void some_function(int param); 

В исходном файле:

#include "test.h" 

void some_function(const int param) {} 

int main(void) { 
    return 0; 
} 

Под Visual Studio 2010, компиляция как чистый проект C, я вижу warning C4028: formal parameter 1 different from declaration. Но, насколько я знаю, это вполне допустимая C и довольно распространенная практика.

Неужели я ошибаюсь, и VS2010 поэтому правильно предупредил меня? Или, если это ложное предупреждение, могу ли я его отключить специально для такого рода случаев, но предупреждайте ли вы о реальных случаях несогласованных типов параметров?

(Действительное компилятор, который поставляется с VS2010 является: Microsoft (R) 32-битный C/C++ оптимизирующий компилятор версии 16.00.30319.01 для 80x86 Моя командная строка просто cl test.c.).

+0

Интересно. Где вы видели это в «обычной практике»? И да, правильно предупредить вас, хотя в этом случае не имеет значения, чтобы лизать, так как его параметр значения, и более ограничительный для стороны реализации для загрузки. Сделайте это с помощью * указателя *, и это сделает * большую * разницу. Пример: рассмотрим ветвления 'const char *', находящиеся в * prototype * и 'char *' в реализации. – WhozCraig

+0

@WhozCraig - эквивалент с параметром указателя будет 'char * const param', но не' const char * param'. – detly

+0

@WhozCraig - Но да, я знаю, это не имеет значения, это моя точка зрения. Это говорит компилятору и любому разработчику, что параметр «param» не может быть изменен телом функции, который является деталью реализации, которая не должна отображаться в объявлении. Итак, почему VS2010 выдает предупреждение, когда нет никакой несовместимости, нет различий в поведении и нет возможности непредвиденного поведения? – detly

ответ

1

C89 3.5.4.3 Function declarators имеет это сказать о параметрах:

Для двух типов функций, которые должны быть совместимыми, оба должны указывать совместимые типы возврата. Более того, списки типов параметров, если они оба присутствуют, должны согласовывать число параметров и использовать терминатор с многоточием; соответствующие параметры должны иметь совместимые типы.

В разделе 3.1.2.6 Compatible type and composite type указаны совместимые типы, аналогичные типу. Он ссылается 3.5.3 для определителей типа (из которых const один) и что состояний:

Для два квалифицированных типов, чтобы быть совместимыми, то оба имеют одинаково квалифицированное версии совместимого типа; порядок классификаторов типов в списке спецификаторов или квалификаторов не влияет на указанный тип.

Теперь вы обычно считаете, что таким образом int и const int являются не совместимых типов. Тем не менее, я считаю, что это неправильное чтение стандарта просто потому, что int не является квалифицированным типом, поэтому приведенная выше цитата не применяется.

Там это более применима цитатой позже в 3.5.4.3 заявив:

Для каждого параметра, объявленный с квалифицированным типом, его типом для этих сравнений является безоговорочной версией своего заявленного типа.

Следовательно, int и const int сравниваются аналогичным образом и должны быть разрешены. Но это означает, что это не ошибка в соответствии со стандартом. Возможно, Microsoft в своей мудрости все еще думает, что это подозрительное действие и хорошая причина выкачать предупреждение.

Даже если вы считаете, что проблема, очень маловероятно, что Microsoft исправит это для вас (см. Ниже).

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

Это потому, что Microsoft не делает секрета, что Visual C++ является, прежде всего ++ компилятором C и может компилировать код C только на раннее itertions стандарта, в соответствии с here:

Спасибо, что нашли время, чтобы отправить нам ваше предложение. В настоящее время нет планов по внедрению поддержки C99 в VS2010. После завершения этого цикла продуктов мы рассмотрим все предложения клиентов, в том числе и это, для нашего будущего планирования. - Марк Робертс, Microsoft.

И от wikipedia page:

Согласно Herb Sutter, компилятор Си включается только для «исторических причин» и не планируется дальнейшее развитие. Пользователям рекомендуется использовать только подмножество языка C, которое также является допустимым C++, а затем использовать компилятор C++ для компиляции своего кода или просто использовать другой компилятор, такой как Intel C++ Compiler или GNU Compiler Collection.

Это подтверждается в собственном блоге Герба Саттера, соответствующей статье here:

Мы не планируем поддерживать функции ISO C, которые не являются частью ни C90 или ISO C++.

+0

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

+0

Отличный ответ, хотя. Я нашел 3.1.2.6 несколько озадаченным. – detly

 Смежные вопросы

  • Нет связанных вопросов^_^