глобальное внешнее разъяснение - PullRequest
3 голосов
/ 28 декабря 2010

Объявляет ли extern const или просто extern то же самое в заголовочном файле?Также оба будут давать внешнюю связь?

globals.cpp

#include <string>

extern const std::string foo = "bar";

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern const std::string foo;

#endif  /* GLOBALS_H */

ИЛИ

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern std::string foo;

#endif  /* GLOBALS_H */

Оба компилируются и работают нормально, оба дают один и тот же адрес при использовании в нескольких файлах, какой из них более правильный?

Ответы [ 5 ]

3 голосов
/ 28 декабря 2010

Это правильно,

//globals.h

extern const std::string foo; //Consistent

Последовательно!

1 голос
/ 28 декабря 2010

Единственная причина, по которой они оба хорошо компилируются, заключается в том, что вы на самом деле не используете foo, поэтому не имеет значения, может ли компоновщик найти foo или нет (он никогда не пытается). (Или ваш компилятор / компоновщик - мусор. :))

Согласованный заголовок в порядке. Тот, в котором отсутствует const, не является и будет / должен привести к ошибкам, если что-то попытается использовать foo.

Если вы создадите какой-нибудь файл (не globals.cpp), который включает в себя globals.h и попытается использовать foo (например, просто добавьте строку с функцией "foo.c_str ();" в функцию), вы получите ссылку ошибка, потому что const std::string foo не найдено.

Так и должно быть. Заголовок говорит обо всем, что хочет использовать foo, что он может только читать, но не изменять его. Вещи, которые включают заголовок globals.h, не имеют представления о том, что находится внутри globals.cpp; если вы хотите, чтобы они рассматривали объект как const, вы должны поместить эту информацию в файл, который они включают.

1 голос
/ 28 декабря 2010

Правильным является

extern const std::string foo;

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

1 голос
/ 28 декабря 2010

Вы можете дать константную внешнюю связь, как в вашем примере, но она все еще не модифицируема (постоянна). Постскриптум вам нужно включить <string>, а не <iostream>

P.P.S. Если бы я не был ясен, вы не можете переопределить константу. Это не скомпилируется:

extern std::string foo;
extern const std::string foo = "bar";
0 голосов
/ 24 августа 2018

Для языка C объявите фактическое const в файле .c и используйте для него extern в файле заголовка (.h).Это должно быть как обычно при объявлении глобальной переменной.

...