2016-08-12 9 views
1

Мне нужно сохранить код, написанный другими. И я просто наткнулся на многие функции, объявленные внутри одной функции и определенные в другом месте. Например:Почему некоторые люди объявляют функции extern внутри одной функции?

int func(){ 
    ... 
    extern func1(); 
    extern func2(); 
    ... 

} 

Почему они объявляют и определяют функции, как это почему они не заявляют, что функции снаружи? В чем преимущества?

+1

Лично я считаю, что эти декларации - плохая идея. Другие люди согласны со мной, потому что gcc имеет возможность предупреждать о них: '-Wnested-externs'. – melpomene

+0

Я хочу знать преимущества такого рода практики. @ Maharaj –

+0

Почему бы и нет? Возможно, вам это не понравится, но это законно. C. – EJP

ответ

1

Единственная цель - уменьшить область видимости внешних объявлений.

+0

Все еще не понимаете, не могли бы вы объяснить это подробно[email protected] –

+0

Да, но в чем смысл сокращения объема? – melpomene

+1

@melpomene Я предполагаю, что точка такая же, как и для других методов снижения масштаба - избегайте загрязнения глобальной области ненужными объявлениями. Но, да, это плохая идея. – Sergio

6

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

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

Если код написан так, это делается из лени и, возможно, из желания заложить ловушки для будущих разработчиков. Вы также можете видеть, что декларации используют устаревший стиль: extern func1() означает, что func1 возвращает int (по умолчанию) и что он принимает неизвестное, но фиксированное количество параметров. Поэтому вы (и компилятор) даже не знаете, как это назвать.

Допустим, функция была реализована в виде

int func1 (int arg) 

и реализатор решил, что должен быть изменен на

void func1 (int arg, int* result) 

возвращает значение через указатель, а не в качестве результата функции. Странная декларация будет гарантировать, что компилятор не сможет обнаружить это и вызвать func1 после того, как изменение, скорее всего, произойдет сбой, или, что еще хуже, переопределить случайный int где-то в вашем приложении. Это катастрофа в ожидании. Если вы видите такой код в своем приложении, исправьте его немедленно.

1

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

int func(void) { 
    extern int func1(); 
    return func1(); 
} 

int func2(void) { 
    return func1(); // declaration out of scope 
} 

Это ОЧЕНЬ ПЛОХО практика позволяет декларирование func1 быть локальными по отношению к телу функции func. Объявление func1 не имеет никакого эффекта после окончания функции func. На практике современные компиляторы отслеживают такие сомнительные заявления и жалуются.

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

 Смежные вопросы

  • Нет связанных вопросов^_^