Deprecazione della parola chiave statica ... non più?


89

In C ++ è possibile utilizzare la staticparola chiave all'interno di un'unità di traduzione per influenzare la visibilità di un simbolo (dichiarazione di variabile o funzione).

In n3092, questo era deprecato:

Allegato D.2 [depr.static]
L'uso della parola chiave static è deprecato quando si dichiarano oggetti nell'ambito dello spazio dei nomi (vedere 3.3.6).

In n3225, questo è stato rimosso.

L' unico articolo che ho trovato è un po 'informale.

Sottolinea però che per compatibilità con C (e la capacità di compilare programmi C come C ++) la deprecazione è fastidiosa. Tuttavia, compilare un programma C direttamente come C ++ può già essere un'esperienza frustrante, quindi non sono sicuro che meriti considerazione.

Qualcuno sa perché è stato cambiato?


3
Dichiarate oggetti nell'ambito dello spazio dei nomi in C?
Etienne de Martel

heh, grazie, ho trovato dove trovarlo. Ho provato a cancellare il commento ma mi hai battuto lì.
Edward Strange

Questione è stata sollevata da stackoverflow.com/questions/4725204/...
Fred Nurk

1
Questo dà anche al Comitato C ++ l'opportunità di unundeprecare qualcosa nella prossima versione dello Standard :-)
James McNellis

Risposte:


75

In C ++ Standard Core Language Defect Reports and Accepted Issues, Revision 94 under 1012. Undeprecating static `they note:

Sebbene 7.3.1.1 [namespace.unnamed] affermi che l'uso della parola chiave static per dichiarare le variabili nell'ambito dello spazio dei nomi è deprecato perché lo spazio dei nomi senza nome fornisce un'alternativa superiore, è improbabile che la funzione venga rimossa in qualsiasi momento nel prossimo futuro .

Fondamentalmente dire che la deprecazione di staticnon ha davvero senso. Non verrà mai rimosso da C ++ ed è comunque utile perché non è necessario il codice boilerplate necessario con spazi dei nomi senza nome, se si desidera solo dichiarare una funzione o un oggetto con collegamento interno.


2
Bene, sembra che la deprecazione incoraggerebbe le persone a utilizzare invece spazi dei nomi senza nome, il che sarebbe una buona cosa.
sbi

1
@unaperson: Se non altro, perché i namespace senza nome forniscono lo stesso meccanismo per rendere variabili, costanti, funzioni e tipi interni alla loro TU. static class ... , OTOH, non funzionerà.
sbi

2
@nbt: Perché non puoi usare simboli statici come argomenti del modello e perché molti neofiti troverebbero statico più facile da usare e quindi non tentano di provare <functional> e <algorithm> et al. Solo un pensiero veloce.
Sebastian Mach

3
"perché non hai bisogno del codice boilerplate di cui hai bisogno con spazi dei nomi senza nome"? Quale "codice boilerplate"? Qualcosa oltre " namespace {" e " }"?
dal

1
@ErikAronesty Se hai una "classe locale" in un altro file con lo stesso nome, commetterai una violazione ODR.
LF

32

Cercherò di rispondere alla tua domanda, anche se è una vecchia domanda e non sembra molto importante (in realtà non è molto importante in sé ) e ha già ricevuto risposte abbastanza buone. Il motivo per cui voglio rispondere è che si riferisce a questioni fondamentali dell'evoluzione standard e della progettazione del linguaggio quando il linguaggio è basato su un linguaggio esistente: quando le caratteristiche del linguaggio dovrebbero essere deprecate, rimosse o modificate in modi incompatibili?

In C ++ è possibile utilizzare la parola chiave statica all'interno di un'unità di traduzione per influenzare la visibilità di un simbolo (dichiarazione di variabile o funzione).

Il collegamento in realtà.

In n3092, questo era deprecato:

Il ritiro indica:

  • L' intento di rimuovere alcune funzionalità in futuro; questo non significa che le funzionalità deprecate verranno rimosse nella prossima revisione standard, o che debbano essere rimosse "presto", o del tutto. E le funzionalità non deprecate potrebbero essere rimosse nella prossima revisione standard.
  • Un tentativo formale di scoraggiarne l'uso .

Quest'ultimo punto è importante. Sebbene non vi sia mai una promessa formale che il vostro programma non venga infranto, a volte silenziosamente, dallo standard successivo, il comitato dovrebbe cercare di evitare di infrangere il codice "ragionevole". La deprecazione dovrebbe indicare ai programmatori che è irragionevole dipendere da alcune funzionalità .

Sottolinea però che per compatibilità con C (e la capacità di compilare programmi C come C ++) la deprecazione è fastidiosa. Tuttavia, compilare un programma C direttamente come C ++ può già essere un'esperienza frustrante, quindi non sono sicuro che meriti considerazione.

È molto importante preservare un sottoinsieme comune C / C ++, specialmente per i file di intestazione. Naturalmente, le staticdichiarazioni globali sono dichiarazioni di simboli con collegamento interno e questo non è molto utile in un file di intestazione.

Ma il problema non è mai solo la compatibilità con C, è la compatibilità con il C ++ esistente: ci sono tonnellate di programmi C ++ validi esistenti che utilizzano staticdichiarazioni globali. Questo codice non è solo formalmente legale, è valido, poiché utilizza una funzionalità del linguaggio ben definita nel modo in cui è inteso essere utilizzato .

Solo perché ora esiste un "modo migliore" (secondo alcuni) per fare qualcosa non rende i programmi scritti alla vecchia maniera "cattivi" o "irragionevoli". La capacità di utilizzare la staticparola chiave su dichiarazioni di oggetti e funzioni a livello globale è ben compresa nelle comunità C e C ++ e molto spesso utilizzata correttamente.

Allo stesso modo, non cambierò i cast in stile C doublein static_cast<double>solo perché "i cast in stile C sono cattivi", poiché static_cast<double>aggiunge zero informazioni e zero sicurezza.

L'idea che ogni volta che viene inventato un nuovo modo di fare qualcosa, tutti i programmatori si affretterebbero a riscrivere il loro codice di lavoro ben definito esistente è semplicemente folle. Se vuoi rimuovere tutta la bruttezza ei problemi C ereditati, non cambi C ++, inventi un nuovo linguaggio di programmazione. Rimuovere a metà un uso di staticdifficilmente rende C ++ meno C-brutto.

Le modifiche al codice richiedono una giustificazione e "il vecchio è cattivo" non è mai una giustificazione per le modifiche al codice.

Le interruzioni dei cambiamenti linguistici richiedono una giustificazione molto forte. Rendere la lingua leggermente più semplice non è mai una giustificazione per un cambiamento radicale.

Le ragioni addotte perché staticè cattivo sono solo notevolmente deboli, e non è nemmeno chiaro perché non sia gli oggetti che le dichiarazioni di funzione siano deprecati insieme - dare loro un trattamento diverso difficilmente rende il C ++ più semplice o più ortogonale.

Quindi, davvero, è una storia triste. Non a causa delle conseguenze pratiche che aveva: aveva esattamente zero conseguenze pratiche. Ma perché mostra una chiara mancanza di buon senso da parte del comitato ISO.


5
Come tu stesso sottolinea, lo scopo di deprecarlo è scoraggiarne l'uso. Eppure non argomentate che scoraggiarne l'uso sia sbagliato. Spero sicuramente che nessuno esca a incoraggiare le persone a utilizzare dichiarazioni statiche con ambito spazio dei nomi su spazi dei nomi anonimi. No, a meno che non abbiano specificamente bisogno di cross-compilare C.
Nicol Bolas

2
Non mi interessa molto delle persone che usano l'ambito globale statico gli spazi dei nomi anonimi, non sto neanche incoraggiando o scoraggiando. Il punto è che se vuoi davvero scoraggiare le persone a usare spazi dei nomi anonimi devi fornire loro delle buone argomentazioni. In pratica, credo che nella maggior parte delle implementazioni le entità dichiarate in uno spazio dei nomi senza nome siano simboli esportati con un nome casuale, aumentando così la tabella di esportazione. Le entità dichiarate come static, OTOH, non vengono esportate in alcun modo. Quindi molte persone scelgono, sulla base di tale osservazione, di utilizzare static.
curioso

2
" Come lei stesso sottolinea, il punto di deprecarlo è scoraggiarne l'uso. " Il punto di scoraggiarne l'uso è che potrebbe sparire un giorno. Il punto è che l'ambito dello spazio dei nomi staticnon scomparirà mai, quindi è sbagliato deprecarlo. " Eppure non si sostiene che scoraggiare il suo utilizzo sia sbagliato. " Non ho visto argomenti convincenti che dimostrino che l'uso di namespace-scope staticè "sbagliato". Deprecarlo solo per scoraggiarne l'uso è sbagliato, perché nessuno crede davvero che sparirà e perché non convince le persone che usarlo è "sbagliato".
curioso

5
L'intera lingua "un giorno scomparirà". Deprecare C ++.
Gare di leggerezza in orbita

2
"Allo stesso modo, non cambierò i cast in stile C per raddoppiare in static_cast <double> solo perché" i cast in stile C sono cattivi ", poiché static_cast <double> aggiunge zero informazioni e zero sicurezza." La mia eterna lotta con molti ingegneri del software che continuano a lamentarsi del mio uso libertino dello stile C getta da un primitivo all'altro.
Makogan

14

Deprecato o meno, la rimozione di questa funzionalità della lingua interromperà i codici esistenti e infastidirebbe le persone.

L'intera cosa della deprecazione statica era solo un pio desiderio sulla falsariga di "gli spazi dei nomi anonimi sono migliori di quelli statici" e "i riferimenti sono puntatori migliori". Lol.


1
"I riferimenti sono puntatori migliori"? No, i puntatori intelligenti sono puntatori più intelligenti. Non è possibile utilizzare riferimenti per la memoria allocata dall'heap, err, archivio gratuito.
Dan Breslau

3
Scusa, ho dimenticato di terminare con una faccina ironica.
Maxim Egorushkin

2
@ Dan: Questo è esattamente ciò che dice questa risposta: "pio desiderio" lungo una linea di pensiero errata simile. Gli spazi dei nomi senza nome sono una caratteristica importante, proprio come lo è global-scope-static, sebbene per motivi leggermente diversi e anche se hanno qualche sovrapposizione nell'applicabilità.
Fred Nurk

@ Fred, @ Maxim: Scusa se ho frainteso o se la mia memoria è difettosa. Ma non classifico "i riferimenti sono puntatori migliori" come equivalenti a "gli spazi dei nomi anonimi sono migliori di quelli statici" come un caso di pio desiderio. Sono ben consapevole del tentativo di rendere quest'ultimo stick, ma non ricordo che nessuno abbia fatto una proposta seria per sostituire i puntatori con riferimenti. Di nuovo, forse è la mia consapevolezza che manca.
Dan Breslau

1
@ DanBreslau: char* foo = new char; char& ref = *foo;Solo perché ti viene dato un puntatore inizialmente non dice nulla sulla tua capacità di usare i riferimenti.
Gare di leggerezza in orbita il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.