Статическое ключевое слово в объявлении функции может отсутствовать в определении функции? - PullRequest
9 голосов
/ 10 марта 2011

Я хочу иметь статическую функцию, которую я объявляю в своем файле .c перед ее определением:

//file a.c version 1
static int foo();
...
static int foo()
{
...
}

Однако, похоже, я могу оставить ключевое слово static вне определения функции иЯ не получаю предупреждений компилятора ... например,

//file a.c version 2
static int foo();
...
int foo()
{
...
}

Правильно ли я считаю, что эти две формы абсолютно одинаковы?
Если да, то почему допускается такое расхождение и какую форму мне следует использовать?

Ответы [ 5 ]

8 голосов
/ 10 марта 2011

Да 7.1.1 / 6

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

См. Также примеры 7.1.1 / 7

.
4 голосов
/ 10 марта 2011

7.1.1 / 7:

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

7.1.1 / 6: (Спасибо Стиву - этотакже необходимо, чтобы ответ был ясным)

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

Да, эти два одинаковы.

Однако это недопустимо:

int foo();

static int foo() {
  return 0;
}
1 голос
/ 10 марта 2011

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

таким образом мы избегаем дискуссий о языке компилятора и т. Д.

0 голосов
/ 10 марта 2011

В качестве идентификатора C ++ предоставляет превосходную альтернативу static.Вы также можете использовать безымянное пространство имен здесь

Пример,

namespace 
{  
   void f()
   {
   }
}

См. Эти:

Превосходство безымянного пространства имен над статическим?
Почему безымянное пространство имен является «превосходящей» альтернативой статическому?

0 голосов
/ 10 марта 2011

Статический атрибут меняет видимость на единицу компиляции. Это позволяет использовать одно и то же имя в разных файлах для разных целей. Вы должны использовать статику только один раз. Если у вас есть прототип, вы должны сделать здесь.

Когда вы запрашиваете C++, вы не должны использовать статическое, но анонимное пространство имен, чтобы сделать symbold приватным для модуля компиляции:

namespace {
    int foo();
}

void bar()
{
    foo();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...