void display(void);
— это предварительное объявление функции. Он имеет формат прототипа.
Как указано в размещенной ссылке, функция prototype представляет собой объявление функции с указанными типами всех параметров. Если параметров нет, то список параметров должен быть (void)
(без параметров), а не ()
(любой параметр).
Точное правило 8.2 гласит:
Правило 8.2 Типы функций должны быть в форме прототипа с именованными параметрами.
В представленном обосновании (читай, оно довольно хорошее) упоминается, что это делается для того, чтобы избежать старых программ K&R и C90, в которых указаны не все параметры. C99 по-прежнему допускает это в некоторой степени, пока типы параметров в объявлении функции не конфликтуют с типами параметров в определении функции.
По сути, правило направлено на запрет таких функций:
void func1 (x) // K&R style
int x;
{}
void func2(x) // sloppy style
{}
Все параметры (если они есть) должны иметь указанные типы и имена.
Однако я не нашел в MISRA-C ничего, что требовало бы от вас написания объявления функции для каждой функции. Это означает, что код вашего примера будет соответствовать этому правилу MISRA с объявлением функции или без него.
Хотя, как я упоминал в предыдущем ответе, написание файлов .c без объявлений функций (в формате прототипа) является небрежной практикой. Если ваши функции должны вызываться в определенном порядке, это должно быть очевидно с помощью дизайна программы, именования функций и комментариев/документации. Не в том порядке, в котором они были объявлены внутри файла .c.
Не должно быть жесткой связи между строкой исходного кода, где функция объявлена в файле .c, и поведением/использованием этой функции.
Вместо этого функции должны быть определены в порядке, который имеет логический смысл. Обычный способ написания файлов .c состоит в том, чтобы хранить все общедоступные функции, объявление функций которых находится в файле .h, в верхней части файла .c. Затем пусть внутренние функции (с static
/внутренней связью) будут внизу. Эта модель требует объявления всех внутренних функций. Другой вариант — поместить все внутренние функции вверху, а общедоступные — внизу. Пока вы последовательны, любой из них в порядке.
Что наиболее важно, так это то, что если определения функций в файле .c переупорядочиваются, это не должно нарушать работу программы или вызывать ошибки компилятора. Самый простой способ обеспечить это — всегда предоставлять объявления функций для каждой отдельной функции в вашей программе.
Обратите внимание, что объявления функций в верхней части файла вовсе не «по-настоящему бесполезны», поскольку они предоставляют краткий обзор всех функций, присутствующих в файле C. Это способ написания самодокументируемого кода.
Обратите внимание, что стандарт C не допускает прототипа для main() в качестве особого случая.
Обратите внимание, что, кроме того, правила 8.7 и 8.8 запрещают вам использовать void display(void)
без static
, поскольку функция используется только в одной единице перевода.
person
Lundin
schedule
05.10.2017
display()
не объявляетсяstatic
, что, конечно, должно быть, если цель состоит в том, чтобы функция была локальной для файла, в котором она находится. - person unwind   schedule 05.10.2017display()
должен быть статическим, но мы можем представить, что он используется и где-то еще. - person nowox   schedule 05.10.2017int32_t foo(int32_t bar) { /*...*/ }
, определена корректно. Если я попытаюсь вызвать эту функцию из другого файла, мне, конечно, нужно, чтобыextern int32_t foo(int32_t bar);
было объявлено в заголовке, НЕ включенном в файл, где объявленоfoo
. Еслиfoo
используется только в одной и той же единице перевода, его необходимо объявить перед использованием. - person nowox   schedule 05.10.2017main()
; для вас это было бы необычно. Каждая другая функция должна иметь прототип в области видимости, прежде чем она будет использована. Есть основания иметь прототип в области действия до его объявления, если только это не статическая функция, и в этом случае ее наличие с полным прототипом (без пустых скобок только потому, что функция не принимает параметров — это C, а не C++) дает прототип. В этом случае функция должна быть определена до ее использования. Правило MISRA разумно (если только оно не предусматривает объявление дляmain()
); вы должны строго следовать ему. - person Jonathan Leffler   schedule 05.10.2017