2013-03-27 4 views
32

Моя книга программирования C говорит, что когда я хочу создать статическую функцию, мне нужно поставить статическое ключевое слово перед функцией определение. В нем ничего конкретно не говорится о прототипе. Кроме того, примеры не используют прототипы и просто ставят статические функции в верхней части файла (так что им не нужны прототипы, которые я предполагаю).Требуется ли статической функции статическое ключевое слово для прототипа в C?

Итак, статической функции требуется статическое ключевое слово для прототипа? Или я только поставил перед определением?

+2

Вы пытались скомпилировать 'void foo(); static void foo() {} '? – 2013-03-27 21:38:05

+1

Это один из тех, почему бы вам не попробовать что-то вроде этого. Простота проверки. –

+8

Не перед компьютером, я могу сейчас скомпилировать .. Кроме того, я заметил, что в программировании, просто потому, что он работает в одном примере, не означает, что он будет работать во всех * случаях. – w1res

ответ

32

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

Если есть одна заявка функции static, ее первая декларация должна быть static.

Он определен в стандарте ISO/IEC 9899: 1999, 6.7.1:

Если декларация идентификатора области видимости файла для [...] функция содержит хранения класса спецификатор static, то идентификатор имеет внутреннюю связь.

[...]

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

[...]

Если объявление идентификатора для функции не имеет хранения класса спецификатор, его связи определяется точно так, как если бы она была объявлена ​​с хранением класса спецификатор extern.

[...]

Если в единице трансляции, тот же самый идентификатор появляется с внутренней и внешней связи, поведение не определено.

Так, например,это справедливо:

static void foo(void); 
void foo(void); 
static void foo(void) { } 

Это один тоже:

static void foo(void) { } 
void foo(void); 

static void bar(void); 
void bar(void) {} 

Но этот код неверен:

void foo(void); 
static void foo(void) { } 

Обычно вы и должны иметь static в прототипы тоже (потому что они обычно на первом месте).

+0

static void foo (void) отличается от void foo (void), no? две разные декларации? – 75inchpianist

+1

Нет, это просто избыточное объявление той же функции. –

+2

+1: и напоминание: определение функции служит прототипом; прототип служит объявлением. – pmg

-1

Да, да, вам нужно поставить статическую информацию перед декларацией.

типа это в ideone.com

int add(); 
int main(){ 
    printf("%d",add()); 
    return 0; 
} 

static int add(){ 
    return 1+1; 
} 

вы получите этот результат: http://ideone.com/VzZCiE

теперь типа это

static int add(); 
int main(){ 
    printf("%d",add()); 
    return 0; 
} 

static int add(){ 
    return 1+1; 
} 

вы получите это: http://ideone.com/sz8HVR

boooom

+0

Почему вниз вниз? – 75inchpianist

+8

My downvote - это потому, что ваш ответ неверен. –

+0

как это неправильно? Если вы опустите статику, это не удастся. Даже если вы думаете, что он будет работать с некоторыми компиляторами, он не будет со всеми компиляторами. Вы действительно хотите поощрять специфический код компилятора, когда его можно избежать? – 75inchpianist