Falsos amigos? Palavra-chave “estática” em C em comparação com C ++, C # e Java

8

Para mim, o uso da palavra-chave staticem C e idiomas como C # e Java são "falsos amigos", como "tornar-se" em inglês e "bekommen" em alemão (= "obter" em inglês), porque significam coisas diferentes.

Em C static, significa que a função ou variável é acessível apenas através de funções dentro do mesmo arquivo de origem, comparável a privatefunções e membros em C ++, Java e C #.

Em C ++, Java e C # staticsignifica que os métodos não são membros de uma instância de classe, mas efetivamente são mais ou menos como funções C mais espaço para nome.

IMHO esses dois conceitos são bem diferentes, então por que os designers de C ++ e mais tarde Java e C # escolheram a staticpalavra - chave para esse comportamento? Existe uma conexão lógica que eu sinto falta?

EDIT Eu sei, que staticem C não governa a acessibilidade de maneira semelhante à privatedo C ++, mas pode ser usado dessa maneira, consulte https://stackoverflow.com/a/1479639/124983

Resíduo
fonte

Respostas:

9

Eu tenho um livro sobre o design do C ++ de Bjarne Stroustrup (o inventor do C ++). Eu não o tenho aqui, então não posso procurar a citação exata agora, mas nele ele admite que quando adicionou staticao C ++, ele não entendeu completamente o que isso significava em C. É por isso que em C ++ tem um significado diferente do que em C.

Java e C # herdaram o significado do C ++.

Jesper
fonte
Criou uma conta aqui apenas para votar esta resposta! Esta é uma informação incrível que eu nunca iria querer perder na minha vida como desenvolvedor de software!
Maverick283
@ Maverick283 É este livro: The Design and Evolution of C ++
Jesper
14

Notavelmente, o C ++ tem dois usos static, e acho que há um terceiro em algum lugar.

Geralmente, acho que o uso de C staticnão corresponde a nenhum uso da palavra em inglês, enquanto acho que, staticcomo staticvariável de membro, por exemplo, faz muito mais sentido.

Lembre-se de que, como designer de linguagem, você tem um incentivo justo para introduzir menos palavras-chave na linguagem, para não permitir menos código, especialmente quando você está tentando ser compatível com C, como em C ++, e a staticpalavra - chave já existia, então eles não conseguiram interromper nenhum programa em C que tentasse compilar como C ++ reutilizando-o.

Edit: Eu sabia que havia um terceiro. C possui staticvariáveis ​​no nível da função . O staticmembro é apenas uma versão com escopo dessa funcionalidade. Portanto, ambos os usos são staticoriginários de C.

DeadMG
fonte
3
c tem dois usos de estático (ligação e tempo de vida), c ++ possui esses e a classe one
jk.
1
@jk: A versão da classe é a mesma coisa que o nível da função static, apenas o escopo de uma classe em vez de uma função.
28412 DeadMG
1
@jk. Muitos pensam em staticter três usos em C (variável do escopo da função, escopo da unidade de compilação para variáveis, escopo da unidade de compilação para funções). Realmente está fazendo as duas mesmas coisas nesses três casos (vínculo e tempo de vida), eu compartilho sua opinião sobre isso. Infelizmente, a visão de três usos da estática em C é mais comum. Ajuda as pessoas a entender como usá-lo, mas não como ele realmente funciona.
Gauthier
Você está esquecendo o novo uso C99 de estática: stackoverflow.com/questions/3430315/...
Austin
8

No C ++, staticpossui os quatro usos a seguir :

  • Função global (nível de arquivo) e declarações de variáveis : com estático, você está especificando o vínculo interno . Isso significa que o símbolo é usado apenas nessa unidade de compilação (.cpp / cc / qualquer arquivo, não um cabeçalho). É a isso que você está se referindo como "privado".

  • Variáveis ​​locais : a duração do armazenamento estático especifica que a variável deve reter seu valor entre as chamadas de função.

  • Membros de dados : os membros de dados estáticos são compartilhados entre as instâncias da classe (ou seja, existe apenas uma cópia do membro). Isso é semelhante ao estático em C # e Java.

  • Funções de membro: Funções de membro estáticas são funções de membro que não possuem um thisponteiro implícito ; eles podem ser chamados sem uma instância. Isso também é muito parecido com C # ou Java.

Então, como você pode ver, eles deixaram cair dois dos significados acima. Para o escopo, é bastante compreensível o motivo: tanto o C # quanto o Java (e até o C ++) dependem de espaços para nome para fazer isso. O C ++ provavelmente possui o recurso de ligação interna para compatibilidade com versões anteriores. A exclusão de variáveis ​​locais estáticas é provavelmente dupla: pela primeira vez, pode ser difícil entender completamente suas consequências, e essas linguagens visam a simplicidade. Segundo, Java e C # têm um coletor de lixo que (posso imaginar) causa dificuldades para implementar esse comportamento.

Tamás Szelei
fonte
"O C ++ provavelmente possui o recurso de ligação interna para compatibilidade com versões anteriores." - pode-se acrescentar (IIRC) que o padrão C ++ substituiu primeiro esse uso de static(preferindo espaços de nomes anônimos) e, em seguida, em sua encarnação atual, o C ++ 11 depreciou o uso staticdisso. (all IIRC)
Martin Ba
Mesmo? Tenho certeza de que os compiladores não aceitaram essa depreciação na época, porque ela funcionava com pelo menos duas (mainstream) (gcc e MSVC).
Tamás Szelei 28/03/12
Nenhum compilador jogou fora, tanto quanto eu sei. Ainda acho que o padrão '98 / '03 o depreciou ou algo assim. O que eu realmente queria dizer com o meu comentário foi que a ligação interna é um recurso aparentemente também considerado útil em C ++, portanto, não existe apenas para compatibilidade com versões anteriores.
Martin Ba
A maneira "c ++ - y" de fazer a mesma coisa é declarar em um espaço para nome anônimo.
Tamás Szelei 28/03
"é declarar em um espaço de nome anônimo" - exceto que não é a mesma coisa tecnicamente. (Peço desculpas por não ter mais referências, mas não tenho tempo para pesquisá-las. (Eu acho que foi mencionado no NG moderado comp.lang.c ++.) E talvez seja possível encontrar alguma referência nos documentos padrão de WG21 ...)
Martin Ba
3

O C ++ retirou-o do C, porque o C ++ gosta de reutilizar palavras-chave existentes em vez de introduzir novas, para minimizar a quebra de código existente.

Java e C # então pegaram no C ++.

Martin Ba
fonte
3

C staticnão governa a acessibilidade e não é análogo privateda maneira que você sugere.

No escopo do arquivo, ele governa a disponibilidade do nome (símbolo do vinculador), não da coisa - você pode passar um ponteiro para uma staticfunção ou global da unidade de tradução onde está definido para codificar em outro arquivo e funcionará bem.

A maneira C ++ de fazer isso (como DeadMG diz, a maneira C ainda está disponível também) é usar um espaço para nome anônimo.

No escopo da função, essencialmente substitui a variável local por uma global que só é acessível (pelo nome novamente!) Dentro dessa função - isso é idêntico no C ++ (portanto, não há uma maneira mais C ++ de fazê-lo) .

Quanto ao motivo pelo qual o C ++ usou o staticqualificador para os membros da classe; provavelmente é certo dizer que isso é para minimizar o número de novas palavras-chave introduzidas. (Observe a recente reutilização do auto para comparação).

Chamar dados estáticos por classe (tão implicitamente dados por instância são dinâmicos ) parece bastante intuitivo para mim, mas como não me lembro do processo de formação dessa intuição, não posso realmente comentar objetivamente se isso fazia sentido ao iniciar. Fora.

Sem utilidade
fonte