Предупреждение компилятора для функции, определенной без прототипа в области видимости? - PullRequest
0 голосов
/ 18 мая 2018

[Вопрос навеян потоком комментариев на этом ответе .]

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

Но, выходя за рамки этого, я хочу, чтобы мой компилятор предупредил меня, если я определю функцию без объявления прототипа в области видимости, предположительно включенную из того же заголовочного файла, что извонящие используют.(Если функция не является статической, в этом случае все это является спорным.)

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

Существуют ли распространенные компиляторы, которые могут это проверить?Я пробовал gcc и clang с -Wall, а они нет.(Я полагаю, что Gimpel lint - если он все еще рядом - сделал бы это, но у меня нет копии.)

В идеале, я бы хотел, чтобы он также настаивал на том, что прототип существует вотдельный заголовочный файл, но это другой чайник рыбы, поэтому я не настаиваю на этом.(Причиной этого дополнительного условия может быть то, что некоторые программисты, обеспокоенные гипотетическим предупреждающим сообщением, могут попытаться заставить его замолчать, введя внешний прототип в верхней части файла .c, содержащего определение, что опять-таки приведет к поражениюцель.)

1 Ответ

0 голосов
/ 18 мая 2018

Если вам нужен вариант, который работает как на gcc, так и на clang, то лучше всего подойдет -Wmissing-prototypes .Как указано в документации по gcc, это сработает, если определена глобальная функция и либо:

  • Предыдущее объявление не было;или

  • Предыдущее объявление не имело прототипа.

Не жалуется, если предыдущее объявление содержится в том же файле, что и определение;то есть не требуется, чтобы объявление было в заголовочном файле.

Эта опция должна быть включена явно;он не включается ни -Wall, ни -Wextra.

К сожалению, gcc допускает эту опцию только для C и Objective C;не для C ++ (предположительно, потому что C ++ не допускает объявления функций без прототипов).Для gcc другой возможностью будет -Wmissing-декларации .Это предупреждение выдается только в том случае, если не было предыдущего объявления;предыдущее объявление без прототипа (т.е. int foo();) не сообщается.Но это работает как на C, так и на C ++.Опять же, опция предупреждения должна быть включена явно.

Clang также имеет опцию -Wmissing-declarations, но это означает что-то совершенно другое, и он включается автоматически (даже если нет опций -W).Например, этот параметр контролирует жалобы на пустые объявления (int;), пустые определения типов (typedef int;) и нетегированные композиции, которые не объявляют ни одного объекта (struct { int a; };).Gcc также выдает предупреждения об этих конструкциях, но нет очевидной возможности включить или отключить эти предупреждения.

...