Законно ли помещать прототипы функций в основную или другую функцию? - PullRequest
2 голосов
/ 01 декабря 2011

На языке C ++ допустимо ли размещать прототипы функций внутри main или другой функции?Это плохая практика?Зачем кому-то ставить прототипы внутри main?

Ответы [ 2 ]

5 голосов
/ 01 декабря 2011

Очевидно, что лучше всего помещать прототипы в собственный заголовок;вне всякой функции:)

Тем не менее, это законно:

#include <stdio.h>

int
main (int argc, char *argv[])
{
  void foo ();

  foo ();
  return 0;
}

void foo ()
{
  printf ("Foo!\n");
}
2 голосов
/ 01 декабря 2011

Да, это законно - в этом нет никаких сомнений.Однако обычно это нежелательно.

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

Дополнительновы теряете основное преимущество перекрестной проверки.Лучший способ сделать это:

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

Таким образом, если вам нужночтобы изменить объявление функции, у вас есть меньше мест для отслеживания.Если у вас есть функция, объявленная в нескольких местах, вы должны изменить все объявления одновременно.Конечно, для достаточно радикального изменения (дополнительных аргументов или меньшего количества аргументов) вам придется изменить вызовы функции;для других изменений (таких как добавление квалификатора const к аргументу или переход от передачи по значению к передаче по ссылке) вам может не потребоваться что-либо менять в источнике;простой перекомпиляции может быть достаточно.

...