¿Amigos falsos? Palabra clave "estática" en C en comparación con C ++, C # y Java

8

Para mí, el uso de la palabra clave staticen C y lenguajes como C # y Java son "falsos amigos" como "convertirse" en inglés y "bekommen" en alemán (= "obtener" en inglés), porque significan cosas diferentes.

En C staticsignifica que la función o variable solo es accesible a través de funciones dentro del mismo archivo fuente, comparable a privatefunciones y miembros en C ++, Java y C #.

En C ++, Java y C # staticsignifica que los métodos no son miembros de una instancia de clase, sino que son más o menos como funciones de C más espacio de nombres.

En mi humilde opinión, estos dos conceptos son bastante diferentes, entonces, ¿por qué los diseñadores de C ++ y posteriores de Java y C # eligieron la staticpalabra clave para ese comportamiento? ¿Hay una conexión lógica que echo de menos?

EDITAR Sé que staticen C no gobierna la accesibilidad de una manera similar a privateC ++, pero puede usarse de esa manera, consulte https://stackoverflow.com/a/1479639/124983

Residuo
fuente

Respuestas:

9

Tengo un libro sobre el diseño de C ++ por Bjarne Stroustrup (el inventor de C ++). No lo tengo aquí, así que no puedo buscar la cita exacta en este momento, pero en él admite que cuando agregó statica C ++, no entendió completamente lo que significaba en C. Así que por eso en C ++ tiene un significado diferente que en C.

Java y C # heredaron el significado de C ++.

Jesper
fuente
¡Creé una cuenta aquí solo para votar esta respuesta! ¡Esta es una información increíble que nunca me gustaría perder en mi vida como desarrollador de software!
Maverick283
@ Maverick283 Es este libro: El diseño y la evolución de C ++
Jesper
14

Cabe destacar que C ++ tiene ambos usos staticy creo que hay un tercero en alguna parte.

En general, creo que el uso de C staticno se corresponde en absoluto con el uso de la palabra en inglés, mientras que creo que, staticcomo staticvariable miembro, tiene mucho más sentido.

Recuerde que, como diseñador de lenguaje, tiene un incentivo justo para introducir menos palabras clave en el lenguaje, para no permitir menos código, especialmente cuando intenta ser compatible con C, como en C ++, y la staticpalabra clave ya existía, por lo que no pudieron romper ningún programa de C que intentara compilarse como C ++ reutilizándolo.

Editar: Sabía que había un tercero. C tiene staticvariables de nivel de función . El staticmiembro es solo una versión con alcance de esta funcionalidad. Por lo tanto, ambos usos de se staticoriginan en C.

DeadMG
fuente
3
c tiene dos usos de static (vinculación y duración), c ++ tiene ambos y la clase uno
jk.
1
@jk: La versión de la clase es lo mismo que el nivel de función static, solo se enfoca en una clase en lugar de una función.
DeadMG
1
@jk. Muchos piensan en statictener tres usos en C (variable de alcance de función, alcance de unidad de compilación para variables, alcance de unidad de compilación para funciones). Realmente está haciendo las mismas dos cosas en estos tres casos (vinculación y duración), comparto su opinión al respecto. La vista de tres usos de la estática en C es más común, lamentablemente. Ayuda a las personas a entender cómo usarlo, pero no cómo funciona realmente.
Gauthier
Olvida el nuevo uso de estática C99: stackoverflow.com/questions/3430315/…
Austin
la respuesta a continuación es la mejor: softwareengineering.stackexchange.com/a/141880/253741 , pero para comparación - 2 en C: stackoverflow.com/a/728586/1200764 - C vs C ++: stackoverflow.com/a/29224988/1200764 - 3 en C ++: cprogramming.com/tutorial/statickeyword.html
WillC
8

En C ++, statictiene los siguientes cuatro usos:

  • Función global (nivel de archivo) y declaraciones de variables : con static, está especificando un enlace interno . Eso significa que el símbolo solo se usa en esa unidad de compilación (.cpp / cc / cualquier archivo, no un encabezado). Esto es a lo que se refiere como "privado".

  • Variables locales : la duración del almacenamiento estático especifica que la variable debe conservar su valor entre las llamadas a funciones.

  • Miembros de datos : los miembros de datos estáticos se comparten entre las instancias de la clase (es decir, solo hay una copia del miembro). Esto es similar a C # y Java estático.

  • Funciones miembro : las funciones miembro estáticas son funciones miembro que no tienen un thispuntero implícito ; se pueden invocar sin una instancia. Esto también es muy parecido a C # o Java.

Entonces, como puede ver, dejaron caer dos de los significados anteriores. Para el alcance, es bastante comprensible por qué: tanto C # como Java (e incluso C ++) se basan en espacios de nombres para hacerlo. C ++ probablemente tiene la función de enlace interno para compatibilidad con versiones anteriores. El abandono de las variables locales estáticas es probablemente doble: por una vez, puede ser difícil comprender completamente sus consecuencias, y estos lenguajes apuntan a la simplicidad. En segundo lugar, tanto Java como C # tienen un recolector de basura que (me imagino) causa dificultades para implementar dicho comportamiento.

Tamás Szelei
fuente
"C ++ probablemente tiene la función de enlace interno para compatibilidad con versiones anteriores". - se podría agregar (IIRC) que el Estándar C ++ primero desaprobó este uso de static(prefiriendo espacios de nombres anónimos) y luego, en su encarnación actual, C ++ 11 desaprobó el uso de staticesto. (todos IIRC)
Martin Ba
De Verdad? Estoy bastante seguro de que los compiladores no respetaron esta depreciación entonces, porque funcionó con al menos dos mainstream (gcc y MSVC).
Tamás Szelei
Ningún compilador lo tiró hasta donde yo sé. Aún así, creo que el estándar '98 / '03 lo desaprobó o algo así. Lo que realmente quería decir con mi comentario era que el enlace interno es una característica que aparentemente también se considera útil en C ++, por lo que no solo existe para la compatibilidad con versiones anteriores.
Martin Ba
La forma "c ++ - y" de hacer lo mismo es declarar en un espacio de nombres anónimo.
Tamás Szelei
"es declarar en un espacio de nombres anónimo", excepto que técnicamente no es lo mismo. (Me disculpo por no tener más referencias, pero me falta el tiempo para buscarlo. (Creo que se mencionó en comp.lang.c ++. Moderado NG, y tal vez uno puede encontrar alguna referencia en los documentos estándar) de WG21 ...)
Martin Ba
3

C ++ lo tomó de C, porque a C ++ le gusta reutilizar las palabras clave existentes en lugar de introducir otras nuevas, para minimizar la ruptura del código existente.

Java y C # lo tomaron de C ++.

Martin Ba
fuente
3

C staticno gobierna la accesibilidad, y no es análogo a privatela forma en que sugiere.

En el ámbito del archivo, gobierna la disponibilidad del nombre (símbolo del enlazador), no la cosa: puede pasar un puntero a una staticfunción o global desde la unidad de traducción donde se define para codificar en otro archivo, y funcionará bien.

La forma en C ++ de hacerlo (como dice DeadMG, la forma en C todavía está disponible también) es usar un espacio de nombres anónimo.

En el ámbito de la función, esencialmente reemplaza la variable local con una global que solo es accesible (¡por nombre de nuevo!) Dentro de esa función; esto es idéntico en C ++ (por lo tanto, no hay una manera más C ++ de hacerlo) .

En cuanto a por qué C ++ usó el staticcalificador para los miembros de la clase; Probablemente sea correcto decir que esto es para minimizar la cantidad de palabras clave nuevas introducidas. (Tenga en cuenta la reciente reutilización de auto para la comparación).

Llamar a los datos por clase estáticos (de manera implícita, los datos por instancia son dinámicos ) me parece bastante intuitivo, pero como no recuerdo el proceso de formación de esa intuición, no puedo comentar objetivamente si tenía sentido al comenzar fuera.

Inútil
fuente