Descontinuação da palavra-chave estática ... não mais?

87

Em C ++, é possível usar a staticpalavra - chave em uma unidade de tradução para afetar a visibilidade de um símbolo (variável ou declaração de função).

No n3092, isso foi descontinuado:

Anexo D.2 [depr.static]
O uso da palavra-chave static é descontinuado ao declarar objetos no escopo do namespace (ver 3.3.6).

No n3225, isso foi removido.

O único artigo que consegui encontrar é um tanto informal.

No entanto, ele destaca que, para compatibilidade com C (e a capacidade de compilar programas C como C ++), a depreciação é irritante. No entanto, compilar um programa C diretamente como C ++ já pode ser uma experiência frustrante, portanto, não tenho certeza se merece consideração.

Alguém sabe por que foi alterado?

Matthieu M.
fonte
3
Você declara objetos no escopo do namespace em C?
Etienne de Martel
heh, thx, descobri onde encontrá-lo em. Tentei deletar o comentário, mas você me venceu.
Edward Strange
A pergunta surgiu em stackoverflow.com/questions/4725204/…
Fred Nurk
1
Isso também dá ao Comitê C ++ a oportunidade de desaprovar algo na próxima versão do Padrão :-)
James McNellis

Respostas:

74

Em C ++ Standard Core Language Defect Reports and Accepted Issues, Revisão 94 sob 1012. Undeprecating static `eles observam:

Embora 7.3.1.1 [namespace.unnamed] indique que o uso da palavra-chave estática para declarar variáveis ​​no escopo do namespace está obsoleto porque o namespace sem nome fornece uma alternativa superior, é improvável que o recurso seja removido em qualquer ponto no futuro previsível .

Basicamente, dizendo que a depreciação de staticnão faz sentido. Ele nunca será removido do C ++ e ainda é útil porque você não precisa do código clichê de que precisa com namespaces não nomeados, se quiser apenas declarar uma função ou objeto com ligação interna.

Johannes Schaub - litb
fonte
2
Bem, parece que a depreciação encorajaria as pessoas a usar namespaces sem nome, o que seria uma coisa boa.
sbi
1
@unaperson: Se por nenhuma outra razão, então porque os namespaces não nomeados fornecem o mesmo mecanismo para tornar variáveis, constantes, funções e tipos internos em sua TU. static class ... , OTOH, não funcionará.
sbi
2
@nbt: Porque você não pode usar símbolos estáticos como argumentos de modelo e porque muitos novatos achariam a estática mais fácil de usar e então não tentariam experimentar <functional> e <algorithm> et al. Apenas um pensamento rápido.
Sebastian Mach
2
"porque você não precisa do código clichê que precisa com namespaces sem nome"? O que "código clichê"? Algo além de " namespace {" e " }"?
dia
1
@ErikAronesty Se você tiver uma "classe local" em outro arquivo com o mesmo nome, você cometerá uma violação do ODR.
LF de
32

Tentarei responder à sua pergunta, embora seja uma pergunta antiga e não pareça muito importante (na verdade não é muito importante por si só ), e já recebeu respostas muito boas. O motivo pelo qual desejo responder é que ele se relaciona a questões fundamentais de evolução padrão e design de linguagem quando a linguagem é baseada em uma linguagem existente: quando os recursos da linguagem devem ser descontinuados, removidos ou alterados de maneiras incompatíveis?

Em C ++, é possível usar a palavra-chave estática em uma unidade de tradução para afetar a visibilidade de um símbolo (variável ou declaração de função).

A ligação, na verdade.

No n3092, isso foi descontinuado:

A suspensão de uso indica:

  • A intenção de remover algum recurso no futuro; isso não significa que recursos obsoletos serão removidos na próxima revisão padrão, ou que eles devem ser removidos "em breve", ou de todo. E recursos não obsoletos podem ser removidos na próxima revisão padrão.
  • Uma tentativa formal de desencorajar seu uso .

O último ponto é importante. Embora nunca haja uma promessa formal de que seu programa não será quebrado, às vezes silenciosamente, pelo próximo padrão, o comitê deve tentar evitar quebrar o código "razoável". A depreciação deve dizer aos programadores que não é razoável depender de algum recurso .

No entanto, ele destaca que, para compatibilidade com C (e a capacidade de compilar programas C como C ++), a depreciação é irritante. No entanto, compilar um programa C diretamente como C ++ já pode ser uma experiência frustrante, portanto, não tenho certeza se merece consideração.

É muito importante preservar um subconjunto comum C / C ++, especialmente para arquivos de cabeçalho. Obviamente, staticas declarações globais são declarações de símbolo com ligação interna e isso não é muito útil em um arquivo de cabeçalho.

Mas o problema nunca é apenas compatibilidade com C, é compatibilidade com C ++ existente: há toneladas de programas C ++ válidos existentes que usam staticdeclarações globais. Este código não é apenas formalmente legal, é sólido, pois usa um recurso de linguagem bem definido da forma como deve ser usado .

Só porque agora existe uma "maneira melhor" (de acordo com alguns) de fazer algo não torna os programas escritos à maneira antiga "ruins" ou "irracionais". A capacidade de usar a staticpalavra-chave em declarações de objetos e funções em escopo global é bem compreendida nas comunidades C e C ++ e, na maioria das vezes, usada corretamente.

Na mesma linha, não vou mudar as projeções do estilo C doublepara static_cast<double>apenas porque "as projeções do estilo C são ruins", pois static_cast<double>adiciona zero informação e zero segurança.

A ideia de que sempre que uma nova maneira de fazer algo é inventada, todos os programadores se apressariam em reescrever seu código de trabalho bem definido existente é simplesmente louca. Se você deseja remover toda a feiura e problemas herdados do C, não altere o C ++, mas sim invente uma nova linguagem de programação. Remover pela metade um uso de staticdificilmente torna o C ++ menos feio para C ++.

As mudanças de código precisam de uma justificativa, e "velho é ruim" nunca é uma justificativa para mudanças de código.

Interromper as mudanças de linguagem precisa de uma justificativa muito forte. Tornar a linguagem um pouco mais simples nunca é uma justificativa para uma alteração significativa.

As razões dadas por que staticé ruim são notavelmente fracas, e nem mesmo está claro por que os objetos e as declarações de função não são reprovados juntos - dar a eles um tratamento diferente dificilmente torna o C ++ mais simples ou mais ortogonal.

Então, realmente, é uma história triste. Não por causa das consequências práticas que teve: teve exatamente zero consequências práticas. Mas porque mostra uma clara falta de bom senso do comitê ISO.

cara curioso
fonte
5
Como você mesmo aponta, o ponto de depreciar é desencorajar seu uso. Mesmo assim, você não argumenta que desencorajar seu uso seja errado. Eu certamente espero que ninguém esteja incentivando as pessoas a usar declarações estáticas com escopo de namespace em vez de namespaces anônimos. Não, a menos que eles especificamente precisem compilar C.
Nicol Bolas
2
Não me importo muito com pessoas que usam escopo global staticou namespaces anônimos, também não estou encorajando ou desencorajando. Meu ponto é que, se você realmente deseja desencorajar as pessoas a usarem namespaces anônimos, você deve apresentar um bom argumento. Na prática, acredito que na maioria das implementações as entidades declaradas em um namespace não nomeado são símbolos exportados com um nome aleatório, aumentando assim a tabela de exportação. As entidades declaradas como static, OTOH, não são exportadas de forma alguma. Assim, muitas pessoas escolhem, com base nessa observação, usar static.
curiousguy
2
Como você mesmo assinala, o objetivo de depreciá-lo é desencorajar seu uso. ” O objetivo de desencorajar seu uso é que ele pode desaparecer algum dia. Meu ponto é que o escopo do namespace staticnunca desaparecerá, então é errado descontinuá-lo. “ Ainda assim, você não argumenta que desencorajar seu uso seja errado. ” Não vi nenhum argumento convincente que mostre que o uso de namespace-scope staticseja “errado”. Desaprová-lo apenas para desencorajar seu uso é errado, porque ninguém realmente acredita que ele vai desaparecer e porque ele não convence as pessoas de que usá-lo é "errado".
curioso
5
Toda a linguagem "desaparecerá algum dia". Vamos descontinuar o C ++.
Lightness Races in Orbit
2
"Na mesma linha, não vou mudar as projeções de estilo C para dobrar para static_cast <double> só porque" as projeções de estilo C são ruins ", já que static_cast <double> adiciona zero informações e segurança zero." Minha luta eterna com muitos engenheiros de software que ficam reclamando do meu uso libertino de castes de estilo C de um primitivo para o outro.
Makogan
14

Obsoleto ou não, a remoção desse recurso de idioma quebraria os códigos existentes e incomodaria as pessoas.

Toda essa coisa de depreciação estática era apenas ilusão ao longo das linhas de "namespaces anônimos são melhores do que estáticos" e "referências são melhores indicadores". Ri muito.

Maxim Egorushkin
fonte
1
"As referências são melhores indicadores"? Não, ponteiros inteligentes são ponteiros mais inteligentes. Você não pode usar referências para memória alocada do heap, err, armazenamento gratuito.
Dan Breslau
3
Desculpe, esqueci de terminar com um sorriso irônico.
Maxim Egorushkin
2
@Dan: Isso é exatamente o que esta resposta diz: "pensamento positivo" ao longo de uma linha de pensamento falha semelhante. Os namespaces sem nome são um recurso importante, assim como o global-scope-static, embora por razões ligeiramente diferentes e mesmo que tenham alguma sobreposição na aplicabilidade.
Fred Nurk
@Fred, @Maxim: Desculpe se não entendi ou se minha memória está com defeito. Mas eu não categorizo ​​"referências são melhores indicadores" como sendo equivalentes a "namespaces anônimos são melhores do que estáticos" como um caso de desejo. Estou bem ciente da tentativa de manter este último, mas não me lembro de ninguém ter feito uma proposta séria de substituir ponteiros por referências. Novamente, talvez seja minha própria consciência que está faltando.
Dan Breslau
1
@DanBreslau: char* foo = new char; char& ref = *foo;Só porque você recebeu um ponteiro, inicialmente não diz nada sobre sua capacidade de usar referências.
Lightness Races in Orbit