Existe algum benefício em definir variáveis ​​locais constantes como estáticas (c ++)?


9
void Animation::playAnimation() const
{
    static const int index = 0;
    const std::string& animationFileName = 
    m_animationContainer.getAnimationName(index);
    static const int zOrder = -1;
    static bool isLooping = false;

    AnimationBank::play(animationFileName,
                        zOrder,
                        isLooping);
}

Existe algum benefício em definir variáveis ​​locais constantes como static? Ou é uma prática desnecessária e até ruim.



2
... também, não faça postagens cruzadas : stackoverflow.com/questions/44431574/… "A postagem cruzada é desaprovada, pois leva a respostas fragmentadas espalhadas por toda a rede ..."
gnat

Pergunta editada.
TM

Respostas:


10

Além da resposta muito boa de @ Christophe, o código gerado para a estática é provavelmente pior do que o da variável local; portanto, se você estiver interessado no benefício básico, as estáticas são piores nos processadores modernos.

O motivo é que a estática deve estar localizada em algum lugar da memória que possa ser encontrado por todos os outros encadeamentos e por todas as outras invocações. Isso basicamente significa colocá-los na memória global.

Ao longo dos anos, processadores e compiladores juntos otimizaram significativamente o acesso a variáveis ​​locais devido à popularidade de seu uso, em comparação com outras variáveis, como globais, estáticas e campos. O compilador pode optar por armazenar uma variável local em um registro da CPU e, mesmo que não o faça (para usar a pilha de invocação), toda a pilha está quase certamente no cache. O acesso à pilha geralmente é um modo de endereçamento de deslocamento curto (fora do registro do ponteiro da pilha). No entanto, o acesso a globais ou estáticos geralmente requer um deslocamento estendido ou endereço absoluto; portanto, as instruções resultantes são maiores que o equivalente ao acesso à memória da pilha.

Tudo o que foi dito, devido à combinação de static e const, o compilador pode detectar que pode substituir o valor constante no ponto de uso, portanto, talvez o uso de const atenue o acima. Ainda assim, seu snippet mostra pelo menos uma estatística não-const, portanto, talvez a discussão seja tópica.


6
Você tem certeza de que constantes estáticas precisam ser armazenadas na memória?
MikeMB

5

Não é uma questão de benefícios, mas uma questão de semântica:

  • Uma variável estática em uma função (mesmo uma função de membro) significa que a variável é compartilhada entre todas as chamadas dessa função. Portanto, uma chamada dessa função tem um efeito colateral nas chamadas subseqüentes.

  • Uma variável não estática é exclusiva para cada execução da função.

Portanto, a menos que seja necessário por algum motivo específico e bem justificado, mantenha as variáveis ​​locais não estáticas.

Observação adicional: A variável estática também é compartilhada entre diferentes segmentos. Portanto, chamar essa função de mais de um thread por vez pode resultar em condições de corrida e UB (mesmo que sejam chamados objetos diferentes).


4
A partir do C ++ 11, o padrão define variáveis ​​estáticas const thread thread safe. Variáveis ​​estáticas não-const, por outro lado, não são.
Teimpz

5
Isso é sobre constantes. Eles não podem alterar seu valor, portanto, não há diferença semântica significativa entre constantes compartilhadas entre várias chamadas de função e locais.
MikeMB

A única diferença é se a inicialização tiver efeitos colaterais.
MikeMB

1
@ MikeMB De fato, minha resposta foi geral. Se for um const, o otimizador o propagará de qualquer maneira, seja ele staticou não. Mas ainda há uma diferença sutil: como você apontou, o inicializador de objetos pode usar alguns efeitos colaterais, de modo que escolher estática ou não pode distorcer o comportamento esperado. Por todas essas razões, eu ainda sugiro usar, staticse e somente se, consté realmente algo que está intrinsecamente vinculado à classe. Mostre a intenção no código e deixe o otimizador fazer seu trabalho.
Christophe

Portanto, semanticamente, não faz diferença se a variável é uma constante e seu endereço não é utilizado. O restante da pergunta é: qual deles você deve usar?
user253751

1

Uma variável local é inicializada ou construída toda vez que a função é chamada. Variáveis ​​locais são armazenadas na pilha e, portanto, geralmente são seguras para threads.

Uma variável local estática é inicializada ou construída apenas uma vez; a primeira vez que a função é chamada. Variáveis ​​estáticas locais não são armazenadas na pilha e, portanto, geralmente não são seguras para threads.

Uma variável local const é uma variável que não muda e é inicializada ou construída toda vez que a função é chamada. Variáveis ​​const locais são armazenadas na pilha e, portanto, geralmente são seguras para threads.

Uma variável local const estática é uma variável que não muda e é inicializada ou construída apenas uma vez; a primeira vez que a função é chamada. As variáveis ​​const estáticas locais não são armazenadas na pilha e, portanto, geralmente não são seguras para threads.

Os compiladores podem otimizar variáveis ​​const em uma constante de tempo de compilação.

Os compiladores podem otimizar variáveis ​​não estáticas mantendo-as em registradores e não na pilha.


Por que static constvariáveis locais não são seguras para threads? Seu valor é constante, mesmo que esteja localizado no fígado.
unificada sanduíche de modelagem

@unifiedmodelingsandwich: E se dois threads fizerem a primeira chamada para a função ao mesmo tempo? Em seguida, os dois threads tentariam inicializar essa static constvariável.
Bart van Ingen Schenau 9/17

Não no C ++ 11 eles não. A inicialização dinâmica de estática de função local é segura para threads.
Sebastian Redl

@BartvanIngenSchenau Desde o C ++ 11, a inicialização estática da variável local é segura para threads . OA ainda está correto ao dizer que não é geralmente seguro para threads, mas seria mais preciso dizer que esse é apenas o caso anterior ao C ++ 11.
sanduíche de modelagem unificada

1
@unifiedmodelingsandwich: Obrigado pela informação. Estou principalmente preso em C ++ 03 :-(
Bart van Ingen Schenau
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.