2015-08-12 4 views
2

я работаю с большим C-только проект, и я постоянно получаю укусила следующей проблемой:C - ловить ошибки неправильных параметров

Допустим, у меня есть функция

void MyFunction(int parameter) 
{ 
    printf("parameter: %d\n", parameter); 
} 

, которые обычно вызывается

int aVariable = 5; 
MyFunction(aVariable); 

Однако, по-видимому, из-за стандартных C спецификации, это не вызывает ошибку компиляции:

int aVariable = 5; 
MyFunction(&aVariable); // No error signaled, but causes all sorts of mayhem 

Как я могу уловить эту ошибку, особенно в Visual Studio? Есть ли какая-либо настройка, которую я могу включить, чтобы сделать ее более строгой? Любая стратегия, которую вы могли бы порекомендовать (к тому же «не делать опечатки»)?

Редактировать: Я могу добавить, что из-за (дрянной) природы проекта код образца уже генерирует множество предупреждений; Я не уверен, что смогу удалить всех из них за время, которое у меня есть. Генерирование большего количества предупреждений может быть не лучшим вариантом, однако возможность распознавания этих конкретных предупреждений (как следует из одного ответа) может быть решением этой конкретной проблемы.

+0

Представлен ли компилятор прототипом MyFunction? (до того, как он попадет в строку 'MyFunction (& variable);') – immibis

+1

У вас есть прототипы функций в файлах заголовков? – aschepler

+0

@aschepler Да, у меня есть эта проблема даже с функциями с прототипами, указанными в файлах заголовков. – Alejandro

ответ

3

Если функция MyFunction является объявлено с прототипом до точки вызова, то

MyFunction(&aVariable); 

является подлинным полномасштабным нарушением ограничения в C, то есть это то, что мы обычно называем " ошибка". Вот что говорит спецификация языка. Другими словами, ваша убежденность в том, что это почему-то допускается «из-за стандартных спецификаций C», неверна: это явно запрещено стандартом C.

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

В случае компилятора Visual Studio одним из способов является просмотр номера предупреждения, выданного в таких случаях, и попросить компилятор преобразовать такие предупреждения в ошибки. Это можно сделать либо с помощью #pragma warning, либо через настройки проекта.

+0

Благодарим вас за комментарии. Я начал рассматривать большинство предупреждений и превратил несколько в ошибки, так что независимо от того, что их нельзя игнорировать. Благодарим вас за разъяснение, так как оно помогает выяснить, почему эти ошибки остались незамеченными в первую очередь (прототипы были там и генерировали предупреждения при неправильном использовании, только они потерялись в слишком большом количестве предупреждений!). – Alejandro

2

Вставьте объявление функции вида

void MyFunction(int parameter); 

перед тем, как это назвать. Если вы этого не сделаете, при вызове MyFunction() компилятор C должен принять MyFunction() принимает список переменных аргументов (произвольное число и типы аргументов) и возвращает int.

Следовательно, код будет скомпилирован без ошибок, даже если функция вызывается с неправильными аргументами или вызов кода пытается использовать возвращаемое значение (что не должно выполняться с помощью функции void). Результат, если предоставленные аргументы не соответствуют ожидаемому фактическому определению функции, часто находится в сфере неопределенного поведения.

Объявление функции перед ее вызовом является хорошей практикой и позволяет компилятору обнаруживать проблему и выдавать ошибки или предупреждения по мере необходимости. Без объявления некоторые компиляторы выдают предупреждения, но не все компиляторы делают.

+0

В любом случае он компилируется без ошибок: только предупреждения. –

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