Por que não é necessário decorar um “const char *” com “extern” ao compartilhá-lo entre vários arquivos
Pergunta
Ao ler livros sobre C++, aprendi que para compartilhar uma variável/objeto const entre vários arquivos, precisamos definir a variável const uma vez em um dos arquivos e declará-la em cada arquivo de origem onde ela é usada.Por exemplo,
Em file1.cpp, definimos uma variável const int globalmente como
extern const int ca = 100;
Em file2.cpp onde o usamos, declaramos esta variável como
extern const int ca;
A convenção acima faz todo o sentido para mim.No entanto, quando chegamos a um ponteiro const char, não precisamos defini-lo usando extern, e ele pode ser compartilhado muito bem entre vários arquivos.Por que isso acontece?Por exemplo,
Em file1.cpp, definimos uma variável de ponteiro const char globalmente como
const char *cstr = "hello";
Em file2.cpp onde o usamos, declaramos esta variável como
extern const char *cstr;
Para tornar minha pergunta mais específica, por que o cstr pode ser usado no arquivo2.cpp mesmo que não esteja decorado com "externo" no arquivo1.cpp?
Muito obrigado
Solução
A questão é de ligação.Quando você define uma variável no escopo do espaço para nome e não há declaração anterior que estabeleça a ligação, a ligação externa se o objeto não for const, interno, se for.Então, quando você escreve:
int const ca = 100;
Em um arquivo de origem, a ligação será interna e a entidade (a variável) ca
Refere -se a ser exclusivo dessa unidade de tradução.Se você tivesse escrito:
int ca = 100;
a ligação seria externa, então um
extern int ca;
em outra unidade de tradução se referiria à mesma variável.
E claro, quando você escreve:
char const* cstr = "hello";
Você está definindo um ponteiro, o que não é const (embora aponte para const).
Obviamente, normalmente, você declararia as variáveis em um cabeçalho, com extern
, então haveria uma declaração anterior quando você definir as variáveis e é a primeira declaração que estabelece a ligação.
Outras dicas
extern é usada para tornar explícito que a afirmação "extern const char *cstr;" "" é uma declaração e não uma definição, o CSTR é definido em outro lugar.Se você fez "const char *cstr;" O compilador interpretaria isso como uma definição e você acabaria com 2 variáveis CSTR.
Se você aplicar extern no "const char *cstr =" hello ";" Eu acho que o compilador o ignora porque a inicialização significa que você está definindo a variável.