Понимание extern в C ++ - PullRequest
       15

Понимание extern в C ++

1 голос
/ 25 марта 2010
namespace std  
{ 
  extern istream cin;   
...
}

Используя extern, мы заявляем, что cin определяется в некоторой другой единице как ответ

Но что, если istream определено / не определено в std, должна быть некоторая разница, верно?

В чем разница для компилятора?

Ответы [ 3 ]

2 голосов
/ 25 марта 2010

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

1 голос
/ 25 марта 2010

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

С помощью extern вы можете сказать компилятору "легко, просто, поверьте мне, есть где-то еще объявление и определение для cin класса istream.

Затем компоновщик переходит в действие, и связь между вызовом к использованию cin и самим объектом специально «ожидает». Линкер должен объединить все эти вызовы с их адресатом, и теперь наступает момент, когда факт наличия или отсутствия cin (был скомпилирован или нет) имеет значение. Если нет, то компоновщик не работает. Ошибки, предоставленные компоновщиком, гораздо более загадочны, чем ошибки компилятора, но их интересно исследовать, потому что это очень хороший способ изучения.

Например, следующий фрагмент кода не # включает cstdio, а не stdio.h, но мы знаем, что там будет printf, потому что стандартная библиотека всегда связана с нашей программой. Да, это работает.

extern int printf(const char *, ...);

int main()
{
    printf( "Hello, world!\n" );
}
0 голосов
/ 25 марта 2010

Компилятор должен знать, что istream является типом, и с ключевым словом extern вы говорите ему, что std::cin существует и относится к этому типу. если istream не было объявлено как тип к тому времени, когда компилятор видит строку, он будет жаловаться, сообщая вам, что это не тип.

//extern type var; // error 'type' unknown at this point
class type;
extern type var;   // ok:'type' is a class even if not fully declared
...