Что происходит, когда объявление нестатической функции следует декларации статической функции?

17

Следующие компиляции:

static int foo() { return 1; }
int foo();

Но будет ли он всегда компилироваться? Является ли поведение в этом случае хорошо определенным? И что это значит, когда нестатический прототип следует статическому объявлению?

    
задан Nikita Kiryanov 01.02.2015 в 17:21
источник
  • Примечание: ни один из них не является прототипом (используйте (void) вместо (), чтобы создать прототип) –  M.M 02.02.2015 в 01:30

2 ответа

15

Да, он будет компилироваться, а поведение корректно определено. Поскольку foo объявляется static раньше int foo(); 1 , foo имеет внутреннюю привязку.

C11: 6.2.2 Связывание идентификаторов (p4):

  

Для идентификатора, объявленного с помощью спецификатора класса хранения extern в области видимости, в которой видна предварительная декларация этого идентификатора, 31) , если предыдущее объявление указывает внутренний или внешний привязка, идентификатор идентификатора в последующем объявлении совпадает с привязкой, указанной в предыдущем объявлении . [...]

, и нога отмечает, что:

  

31) Как указано в 6.2.1, более поздняя декларация может скрыть предыдущее объявление.

<суб> 1 . Если класс хранения не указан, предполагается, что функция имеет внешнюю связь. Стандарт говорит: Если декларация идентификатора для функции не имеет спецификатора класса хранения, ее привязка определяется так, как если бы он был объявлен с помощью спецификатора класса хранения extern - 6.2.2 (p5).

    
ответ дан haccks 01.02.2015 в 17:24
  • Но мой прототип не был определен с помощью extern. –  Nikita Kiryanov 01.02.2015 в 17:39
  • @ Никита Кирьянов; Обновлен ответ. –  haccks 01.02.2015 в 17:42
0

По умолчанию функции являются глобальными. Итак, сделав это

static int foo() { return 1; }

Функция foo() видна только в этом файле. Поскольку у вас есть только объявление int foo(); , это хорошо и четко определено, если у вас есть определение для того же int foo(){ return 2;} , после чего вы получите ошибку переопределения .

Как указано @haccks

  

6.2.1, более поздняя декларация может скрыть предыдущее объявление.

Обратите внимание на разницу между объявлением и определением.

    
ответ дан Gopi 01.02.2015 в 17:53