guia - está f(vacío) en desuso en los modernos C y C++
qgis español (6)
En C ++, int f(void)
es de hecho una declaración en desuso que es 100% equivalente a int f()
. Es la misma firma. El void
en este contexto es tan significativo como, por ejemplo, el espacio en blanco. Eso también significa que están sujetos a la Regla de una sola definición (no se sobrecargan) y Derived::f(void)
anula Base::f()
.
Sin embargo, no te metas con cosas como f(const void)
. No hay mucho consenso sobre lo que significa ese tipo de rareza.
Actualmente estoy refabricando / ordenando un viejo código C utilizado en un proyecto de C ++, y veo regularmente funciones como:
int f(void)
que yo tendería a escribir como:
int f()
¿Hay alguna razón para no reemplazar (anular) con () en toda la base del código para mejorar la coherencia, o hay una sutil diferencia entre los dos que desconozco? Más específicamente, si una función de miembro virtual en C ++ se describe como:
virtual int f(void)
y una clase derivada incluye una función miembro:
int f()
¿Es esto una anulación válida? Además, ¿es probable que encuentre algún problema de enlazador basado en firmas casi idénticas?
En C, la declaración int f(void)
significa una función que devuelve int que no toma parámetros. La declaración int f()
significa una función que retorna int que toma cualquier cantidad de parámetros. Por lo tanto, si tiene una función que no toma parámetros en C, la primera es el prototipo correcto.
En C ++, creo que int f(void)
está en desuso, y se prefiere int f()
, ya que significa específicamente una función que no toma parámetros.
Las respuestas anteriores son bastante correctas, pero me estoy vinculando a la excelente página de David Tribble, ya que ofrece una gran explicación sobre este y muchos otros temas.
Los aspectos interesantes:
C distingue entre una función declarada con una lista de parámetros vacía y una función declarada con una lista de parámetros que consta únicamente de vacío. La primera es una función sin prototipo que toma una cantidad no especificada de argumentos, mientras que la segunda es una función de prototipo que no toma argumentos.
C ++, por otro lado, no hace distinción entre las dos declaraciones y las considera a ambas como una función que no toma argumentos.
Para el código que se pretende compilar como C o C ++, la mejor solución para este problema es declarar siempre las funciones que no toman parámetros con un prototipo vacío explícito.
Los prototipos de función vacía son una característica obsoleta en C99 (como lo fueron en C89).
Editar: Después de mirar el estándar, quizás valga la pena señalar que la sintaxis de func (void) no está desaprobada en C ++, pero comúnmente se considera más un estilo de estilo C. Creo que la mayoría de los programadores de C ++ que he encontrado prefieren la lista de parámetros vacía.
Editar 2: Agregar una cita del estándar de C ++, sección 8.3.5, párrafo 2:
"Si la cláusula de declaración de parámetro está vacía, la función no contiene argumentos. La lista de parámetros (vacía) es equivalente a la lista de parámetros vacía. Excepto en este caso especial, el vacío no será un tipo de parámetro (aunque los tipos se derivan del vacío , como void *, can). "
No se menciona que ninguno de los formularios está en desuso. Gracias de nuevo al excelente sitio web del Sr. Tribble por indicarme la sección correcta del estándar.
Para agregar a la respuesta de Chris, usar int f()
es una mala práctica en C, en mi experiencia, ya que se pierde la capacidad del compilador para comparar la declaración de la función con su definición, para garantizar que se invoque correctamente.
Por ejemplo, el siguiente código cumple con los estándares C:
#include <stdio.h>
void foo();
void bar(void) {
foo();
}
void foo(int a) {
printf("%d/n", a);
}
Pero resulta en un comportamiento indefinido, ya que a
no se pasó a foo
.
En C ++, hay dos versiones de foo
: una que no toma argumentos y otra que toma un int
. Así que el bar
termina llamando a la versión indefinida, lo que daría como resultado un error del enlazador (suponiendo que no haya otras definiciones de foo
ninguna parte).
tl; dr: use void
.
Dada la compatibilidad con versiones anteriores en C ++, y el poco de ambigüedad que se identifica a continuación, afirmo que nos remontamos a KnR y ANSI C para obtener una respuesta concluyente:
int getline(void);
int copy(void)
Dado que las versiones especializadas de getline y copy no tienen argumentos, la lógica sugeriría que sus prototipos al principio del archivo deberían ser
getline()
ycopy()
. Pero para la compatibilidad con los programas anteriores de C, el estándar toma una lista vacía como una declaración de estilo antiguo, y desactiva toda comprobación de lista de argumentos; la palabravoid
debe usarse para una lista explícitamente vacía. [Kernighan y Richie, el lenguaje de programación C, 1988, Pgs 32-33]
y..
El significado especial de la lista de argumentos vacíos está destinado a permitir que los programas anteriores de C compilen con compiladores nuevos. Pero es una mala idea usarlo con nuevos programas. Si la función toma argumentos, declarelos; si no requiere argumentos, use void [ibid, Pg. 73]
EDITAR: Interrumpió el resto en una discusión por separado aquí: ¿Especifica el uso de vacío en la declaración de una función que no toma argumentos? ¿El argumento más irritante?
void f()
está en desuso, void f(void)
recomendado:
6.11.6 Declaradores de función :
1 El uso de declaradores de función con paréntesis vacíos (no declaradores de tipo de parámetro de formato de prototipo) es una característica obsoleta.
Introducción :
2 Ciertas características son anticuadas, lo que significa que se pueden considerar su retiro en futuras revisiones de esta Norma Internacional. Se conservan debido a su uso generalizado, pero se desaconseja su uso en nuevas implementaciones (para las características de implementación) o nuevos programas (para el idioma [6.11] o las características de la biblioteca [7.31]).
Discusión detallada: https://.com/a/36292431/895245
Ni void f(void)
ni void f()
están en desuso.
void f(void)
existe para la compatibilidad con C. Anexo C "Compatibilidad" C.1.7 Cláusula 8: declaradores :
8.3.5 Cambio: en C ++, una función declarada con una lista de parámetros vacía no contiene argumentos. En C, una lista de parámetros vacía significa que el número y el tipo de los argumentos de la función son desconocidos.
Como void f()
está en desuso en C y void f(void)
recomendado, void f(void)
existirá mientras C ++ quiera mantener la compatibilidad.
void f(void)
y void f()
son lo mismo en C ++. Por lo tanto, el void f(void)
más largo solo tiene sentido si le interesa escribir código que se compile tanto con C como con C ++, lo que probablemente no valga la pena.
Discusión detallada: https://.com/a/36835303/895245