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.