Редактировать
И в C, и в C ++ наличие extern
указывает на то, что первое объявление не является определением. Следовательно, оно просто делает имя доступным в текущей единице перевода (любой, у кого есть заголовок) и указывает, что указанный объект имеет внешнюю связь, т.е. доступен во всех единицах перевода, составляющих программу. Это не значит, что объект обязательно находится в другой единице перевода - просто «эта строка не является определением».
Конец редактирования
В C extern
является необязательным. Без этого первая декларация является «предварительным определением». Если бы не было более позднего определения (которое однозначно является определением, потому что оно имеет инициализатор), это будет рассматриваться как определение (C99 6.9.2). На самом деле, это просто декларация, и она не конфликтует.
В C ++ extern
не является обязательным - без него первое объявление является определением (C ++ 03 3.1), которое конфликтует со вторым.
Это различие явно указано в Приложении C к C ++:
«Изменение: в C ++ нет« предварительных определений », как в C
Например, в области действия файла,
int i;
int i;
допустимо в C, недействительно в C ++. "