Extern с глобальным определением переменной в c

У меня есть следующий исходный код, который меня интересует.

#include <stdio.h>
extern int foo;
int foo = 32;

int main()
{
printf("%d", foo);
}

Это совершенно нормальный кусок кода, и когда я его компилирую с помощью

gcc -Wall -Wextra -pedantic foo.c

Я не получаю никаких предупреждений.

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

Ответ 1

Нет ничего странного. Сначала вы объявили переменную (вы обещали, что она существует), а затем вы ее определили. Там нет проблем.

Кроме того, по умолчанию все переменные, которые не являются локальными для функций и не определены как static, являются extern.

Ответ 2

Кажется, вы неправильно поняли, что делает extern. extern просто делает ваше объявление просто декларацией вместо определения.

int i; //definition of i
extern int i; //declaration of i

Совершенно нормально иметь несколько деклараций одной и той же переменной, но только одно определение должно присутствовать во всей программе. Сравните это с функцией

void f(void); //declaration
void f(void) //definition(and redeclaration)
{
} //definition

Чтобы использовать переменную или функцию, вам нужно только ее объявление. Его определение может появляться в любом месте программы (его найдет линкер). Anywhere может быть одним и тем же файлом, другим файлом или даже внешней библиотекой.

Ответ 3

И кажется, что это связано с тем, что переменная определена как внешняя, так и глобальная в том же файле.

extern int foo;

говорит: он объявляет без определения объекта типа int с именем foo.

 int foo = 32;

он объявляет и определяет объект типа int с именем foo с внешней привязкой.

Нет противоречия, и это действительно C-код.

Ответ 4

Разница в том, что первая - объявление → extern объявляет переменную и говорит, что она будет доступна где-то вокруг. Вы можете иметь столько объявлений, сколько хотите, а последнее - определение, которое должно быть там ровно один раз.
Поэтому не должно быть никаких предупреждений и ошибок.

Ответ 5

extern - это способ отображения видимости переменной, определенной в другом месте...

extern - это как обещание...

в example.h

extern int g;// promises that this will be in the object code to anything that includes example.h

Пример. с

int g;