Почему extern требуется для прямого объявления глобальных переменных, но не для функций при использовании их из других файлов в C

#c #global-variables #extern #linkage

#c #глобальные переменные #extern #связь

Вопрос:

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

<other.cpp >

 int myNum{888};

int getAnInt()
{
    return 999;
}
  

<main.cpp >

 #include <iostream>

extern int myNum;  // "extern" keyword is required.
int getAnInt();    // "extern" keyword is NOT required.

int main()
{
    std::cout << getAnInt() << "n";
    std::cout << myNum << "n";
}

  

Однако, если нет extern раньше int myNum; . Это произойдет:

 duplicate symbol '_myNum' in:
    /path~~/main.o
    /path~~/other.o
ld: 1 duplicate symbol for architecture x86_64
  

Итак, мой вопрос в том, почему extern требуется для myNum ? Разве глобальные непостоянные переменные не имеют внешней привязки по умолчанию?

Комментарии:

1. потому что extern превращает определение переменной в объявление, хотя int getAnInt(); это уже объявление. Вам разрешено иметь несколько объявлений (при условии, что они идентичны), но только одно определение для каждого объекта.

Ответ №1:

Потому что есть разница между

 int getAnInt(); 
  

и

 int getAnInt() { ... }
  

А именно самих скобок, и как таковой, нет необходимости в маркере like extern для различения между ними.

В частности, первое — это объявление, в котором просто указывается, что getAnInt существует, и возвращается int и т.д., Тогда как второе дает ему свое определение.