Desactivación de la palabra clave estática ... ¿no más?


89

En C ++ es posible usar la staticpalabra clave dentro de una unidad de traducción para afectar la visibilidad de un símbolo (ya sea una variable o declaración de función).

En n3092, esto quedó en desuso:

Anexo D.2 [depr.static]
El uso de la palabra clave estática está en desuso cuando se declaran objetos en el ámbito del espacio de nombres (véase 3.3.6).

En n3225, esto se ha eliminado.

El único artículo que pude encontrar es algo informal.

Sin embargo, subraya que por compatibilidad con C (y la capacidad de compilar programas C como C ++), la desaprobación es molesta. Sin embargo, compilar un programa C directamente como C ++ ya puede ser una experiencia frustrante, por lo que no estoy seguro de si merece consideración.

¿Alguien sabe por qué se cambió?


3
¿Declaras objetos en el ámbito del espacio de nombres en C?
Etienne de Martel

je, gracias, encontré dónde conseguirlo. Intenté borrar el comentario, pero me ganaste.
Edward Strange


1
Esto también le da al Comité de C ++ la oportunidad de eliminar algo en la próxima versión del Estándar :-)
James McNellis

Respuestas:


75

En C ++ Standard Core Language Defect Reports and Accepted Issues, Revisión 94 bajo 1012. Sin prejuicios estáticos , señalan:

Aunque 7.3.1.1 [namespace.unnamed] establece que el uso de la palabra clave estática para declarar variables en el ámbito del espacio de nombres está desaprobado porque el espacio de nombres sin nombre proporciona una alternativa superior, es poco probable que la característica se elimine en cualquier momento en el futuro previsible .

Básicamente decir que la desaprobación de staticrealmente no tiene sentido. Nunca se eliminará de C ++, y sigue siendo útil porque no necesita el código repetitivo que necesita con espacios de nombres sin nombre, si solo desea declarar una función u objeto con enlace interno.


2
Bueno, parece que la desaprobación alentaría a las personas a usar espacios de nombres sin nombre en su lugar, lo que sería bueno.
sbi

1
@unaperson: Si no es por otra razón, entonces porque los espacios de nombres sin nombre proporcionan el mismo mecanismo para hacer variables, constantes, funciones y tipos internos a su TU. static class ... , OTOH, no funcionará.
sbi

2
@nbt: Debido a que no puede usar símbolos estáticos como argumentos de plantilla y porque muchos novatos encontrarían la estática más fácil de usar y luego no tienen la tentación de probar <functional> y <algorithm> et al. Solo un pensamiento rápido.
Sebastian Mach

3
"porque no necesita el código repetitivo que necesita con espacios de nombres sin nombre"? ¿Qué "código repetitivo"? ¿Algo más allá de " namespace {" y " }"?
Towi

1
@ErikAronesty Si tiene una "clase local" en otro archivo con el mismo nombre, cometerá una infracción de ODR.
LF

32

Intentaré responder a su pregunta, aunque es una pregunta antigua, y no parece muy importante (realmente no es muy importante en sí misma ), y ya ha recibido respuestas bastante buenas. La razón por la que quiero responder es que se relaciona con cuestiones fundamentales de la evolución estándar y el diseño del lenguaje cuando el lenguaje se basa en un lenguaje existente: ¿ cuándo se deben desaprobar, eliminar o cambiar las características del lenguaje de formas incompatibles?

En C ++ es posible utilizar la palabra clave estática dentro de una unidad de traducción para afectar la visibilidad de un símbolo (ya sea una variable o declaración de función).

El vínculo en realidad.

En n3092, esto quedó en desuso:

La obsolescencia indica:

  • La intención de eliminar alguna característica en el futuro; esto no significa que las características obsoletas se eliminarán en la próxima revisión estándar, o que deban eliminarse "pronto", o en absoluto. Y las funciones no obsoletas pueden eliminarse en la próxima revisión estándar.
  • Un intento formal de desalentar su uso .

El último punto es importante. Aunque nunca hay una promesa formal de que su programa no se romperá, a veces silenciosamente, por el siguiente estándar, el comité debe tratar de evitar romper el código "razonable". La obsolescencia debería indicar a los programadores que no es razonable depender de alguna característica .

Sin embargo, subraya que por compatibilidad con C (y la capacidad de compilar programas C como C ++), la desaprobación es molesta. Sin embargo, compilar un programa C directamente como C ++ ya puede ser una experiencia frustrante, por lo que no estoy seguro de si merece consideración.

Es muy importante conservar un subconjunto común de C / C ++, especialmente para los archivos de encabezado. Por supuesto, staticlas declaraciones globales son declaraciones de símbolo con enlace interno y esto no es muy útil en un archivo de encabezado.

Pero el problema nunca es solo la compatibilidad con C, es la compatibilidad con C ++ existente: hay toneladas de programas C ++ válidos existentes que usan staticdeclaraciones globales. Este código no solo es formalmente legal, es sólido, ya que utiliza una característica de lenguaje bien definida de la forma en que está destinado a ser utilizado .

El hecho de que ahora haya una "mejor manera" (según algunos) de hacer algo no significa que los programas escritos a la antigua sean "malos" o "irrazonables". La capacidad de usar la staticpalabra clave en declaraciones de objetos y funciones en el ámbito global se comprende bien en las comunidades C y C ++, y la mayoría de las veces se usa correctamente.

En una línea similar, no voy a cambiar los moldes de estilo C doublea static_cast<double>solo porque "los moldes de estilo C son malos", ya que static_cast<double>agrega cero información y cero seguridad.

La idea de que cada vez que se inventa una nueva forma de hacer algo, todos los programadores se apresuran a reescribir su código de trabajo existente bien definido es una locura. Si desea eliminar todos los problemas y la fealdad heredados, no cambia C ++, sino que inventa un nuevo lenguaje de programación. La eliminación de la mitad de un uso de staticapenas hace que C ++ sea menos C-feo.

Los cambios de código necesitan una justificación, y "lo antiguo es malo" nunca es una justificación para los cambios de código.

Romper los cambios de lenguaje necesita una justificación muy sólida. Hacer el lenguaje un poco más simple nunca es una justificación para un cambio radical.

Las razones dadas por las que statices malo son simplemente notablemente débiles, y ni siquiera está claro por qué no tanto los objetos como las declaraciones de funciones están desaprobados juntos; darles un tratamiento diferente difícilmente hace que C ++ sea más simple o más ortogonal.

Entonces, realmente, es una historia triste. No por las consecuencias prácticas que tuvo: tuvo exactamente cero consecuencias prácticas. Pero porque muestra una clara falta de sentido común por parte del comité de ISO.


5
Como usted mismo señala, el objetivo de desaprobarlo es desalentar su uso. Sin embargo, no argumenta que desalentar su uso esté mal. Ciertamente espero que nadie esté animando a la gente a utilizar declaraciones estáticas de ámbito de nombres en espacios de nombres anónimos. No a menos que específicamente necesitan C. transversal de compilación
Nicol Bolas

2
No me importa mucho la gente que usa el alcance global statico los espacios de nombres anónimos, no estoy alentando ni desalentando tampoco. Mi punto es que si realmente quieres disuadir a las personas de que utilicen espacios de nombres anónimos, debes darles un buen argumento. En la práctica, creo que en la mayoría de las implementaciones, las entidades declaradas en un espacio de nombres sin nombre son símbolos exportados con un nombre aleatorio, aumentando así la tabla de exportación. Las entidades declaradas como staticOTOH no se exportan de ninguna manera. Por lo tanto, muchas personas eligen, basándose en esa observación, utilizar static.
curioso

2
" Como usted mismo señala, el punto de desaprobarlo es desalentar su uso. " El punto de desalentar su uso es que podría desaparecer algún día. Mi punto es que el alcance del espacio de nombres staticno desaparecerá nunca, por lo que está mal desaprobarlo. " Sin embargo, no argumenta que desalentar su uso está mal " . No he visto ningún argumento convincente que demuestre que el uso del ámbito de espacio de nombres statices "incorrecto". Despreciarlo solo para desalentar su uso está mal, porque nadie cree realmente que va a desaparecer y porque no convence a la gente de que usarlo es "incorrecto".
curioso

5
Todo el idioma "desaparecerá algún día". Dejemos de C ++.
Lightness Races in Orbit

2
"En una línea similar, no voy a cambiar los lanzamientos de estilo C para duplicar a static_cast <double> solo porque" los lanzamientos de estilo C son malos ", ya que static_cast <double> agrega cero información y cero seguridad". Mi eterna lucha con muchos ingenieros de software que siguen quejándose de mi uso libertino de los moldes de estilo C de un primitivo a otro.
Makogan

14

En desuso o no, eliminar esta función de idioma rompería los códigos existentes y molestaría a la gente.

Todo el asunto de la desaprobación estática fue solo una ilusión en la línea de "los espacios de nombres anónimos son mejores que los estáticos" y "las referencias son mejores indicadores". Jajaja


1
¿"Las referencias son mejores indicadores"? No, los indicadores inteligentes son indicadores más inteligentes. No puede usar referencias para la memoria asignada desde el montón, err, tienda libre.
Dan Breslau

3
Lo siento, olvidé terminarlo con una carita irónica.
Maxim Egorushkin

2
@Dan: Eso es exactamente lo que dice esta respuesta: "ilusiones" a lo largo de una línea de pensamiento defectuosa similar. Los espacios de nombres sin nombre son una característica importante, al igual que lo es global-scope-static, aunque por razones ligeramente diferentes, y aunque tienen cierta superposición en la aplicabilidad.
Fred Nurk

@Fred, @Maxim: Lo siento si entendí mal o si mi memoria es defectuosa. Pero no categorizo ​​"las referencias son mejores indicadores" como equivalente a "los espacios de nombres anónimos son mejores que los estáticos" como un caso de ilusión. Soy muy consciente del intento de hacer que este último se mantenga, pero no recuerdo que nadie haya hecho una propuesta seria para reemplazar los punteros con referencias. Una vez más, tal vez sea mi propia conciencia la que falta.
Dan Breslau

1
@DanBreslau: El char* foo = new char; char& ref = *foo;hecho de que se le dé un puntero inicialmente no dice nada sobre su capacidad para usar referencias.
Lightness Races in Orbit
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.