globais estáticos e namespaces anônimos em C ++


11
  1. Por que o C ++ fez alguma distinção entre globais estáticos (ligação interna) e símbolos em um espaço para nome sem nome (ligação externa, mas não há como se referir a ela de fora de qualquer maneira), ao introduzir a última?

  2. Algum desses motivos ainda é válido ou existem novos?

  3. Ainda existem lugares onde ainda são diferentes, mas a regra arbitrária de que as uniões globais anônimas (ou com espaço de nome) devem serstatic e quais são?

  4. Para pontos de bônus, se não houver boas razões para serem diferentes, existe um pedido para torná-los equivalentes?


Quando o C ++ introduziu namespaces (C ++ 98) e, especificamente, os namespaces sem nome, os globos estáticos foram preteridos como obsoletos e inferiores à novidade em um momento de entusiasmo, embora isso tenha sido revertido com o C ++ 11 :
Deprecação da palavra-chave estática… não mais?

Antes do C ++ 11, os símbolos com ligação interna não podiam ser usados ​​como argumentos do modelo: Por que o C ++ 03 exigia que os parâmetros do modelo tivessem ligação externa?


Parece que você respondeu mais à sua própria pergunta, exceto pelo bit "implementação em conformidade"; talvez você deva considerar remover a segunda metade e publicá-la como resposta? Ou ainda há algo sem resposta aqui?
Kyle Strand

@KyleStrand reformulou tudo.
Deduplicator

Respostas:


3

Suponho que isso não responda a todas as suas perguntas (ou alguma?), Mas a principal diferença entre declarações estáticas no nível de arquivo e espaços para nome anônimos é que os espaços para nome também se aplicam aos tipos (você não pode declarar um statictipo no No mesmo sentido em que você declara uma variável), é por isso que o namespace é preferido, para que haja um idioma único para declarar dados e tipos no escopo do arquivo.

Exemplificando, o código a seguir deve compilar perfeitamente. (Não é realmente útil, pois você não pode distinguir entre os dois tipos, mas é permitido)

#include <iostream>

struct Foobar
{
    int   foo;
    float bar;
};

namespace
{

struct Foobar
{
    double baz;
};

} // namespace

int main()
{
    std::cout << "HELLO!\n";
}

Um teste ao vivo aqui .


Compila porque você não usa Foobar na função principal.
dshil

Mais importante, o que acontece se outro arquivo .cpp declarar sua própria versão struct Foobar? Pior ainda, suponha que seja agora class Foobar. Pense em como você planeja criar construtores para os dois.
dgnuff 23/05/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.