void foo()significa "una función que footoma un número no especificado de argumentos de tipo no especificado"
void foo(void)significa "una función fooque no toma argumentos"
En C ++ :
void foo()significa "una función fooque no toma argumentos"
void foo(void)significa "una función fooque no toma argumentos"
Al escribir foo(void), por lo tanto, logramos la misma interpretación en ambos idiomas y hacemos que nuestros encabezados sean multilingües (aunque generalmente tenemos que hacer algunas cosas más a los encabezados para hacerlos realmente en varios idiomas; es decir, envolverlos en un extern "C"si estamos compilando C ++).
Pero si C ++ hubiera requerido el void, entonces podría haber evitado el problema del "análisis más irritante".
Adrian McCarthy
55
Es cierto, pero hay tantos otros análisis de mierda en C ++ que no tiene sentido hablar de ninguno de ellos.
DrPizza
16
En una pregunta reciente, @James Kanze publicó un dato interesante. Vuelva a publicar aquí para evitar perderlo: las primeras versiones de C no permitían especificar el número de parámetros que una función podría tomar, por void foo()lo tanto, era la única sintaxis para declarar una función. Cuando se introdujeron las firmas, el comité C tuvo que eliminar la ambigüedad del parámetro no de la sintaxis anterior e introducir la void foo(void)sintaxis. C ++ lo tomó por razones de compatibilidad.
Matthieu M.
3
¿Me puede dar un ejemplo de C C90 y más tarde donde usar en void foo()lugar de void foo(void)producirá una diferencia funcional? Es decir, he estado usando la versión sin el vacío durante muchos años y no he visto ningún problema, ¿me estoy perdiendo algo?
chacham15
66
@ chacham15 void foo() { if ( rand() ) foo(5); } compila y ejecuta (causando un comportamiento indefinido a menos que tenga mucha suerte), mientras que void foo(void)con el mismo cuerpo causaría un error de compilación.
MM
39
Me doy cuenta de que su pregunta se refiere a C ++, pero cuando se trata de C, la respuesta se puede encontrar en K&R, páginas 72-73:
Además, si una declaración de función no incluye argumentos, como en
double atof();
eso también se entiende que no se debe suponer nada acerca de los argumentos de atof; toda la comprobación de parámetros está desactivada. Este significado especial de la lista de argumentos vacía está destinado a permitir que los programas C más antiguos se compilen con nuevos compiladores. Pero es una mala idea usarlo con nuevos programas. Si la función toma argumentos, declarelos; si no requiere argumentos, use void.
Pero la pregunta es acerca de las definiciones, en ese caso la regla C relevante es Una lista vacía en un declarador de función que es parte de una definición de esa función especifica que la función no tiene parámetros.
Anexo C "Compatibilidad" C.1.7 Cláusula 8: los declarantes dicen:
8.3.5 Cambio: en C ++, una función declarada con una lista de parámetros vacía no toma 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.
Ejemplo:
int f();// means int f(void) in C ++// int f( unknown ) in C
Justificación: Esto es para evitar llamadas de función erróneas (es decir, llamadas de función con el número o tipo de argumentos incorrectos)
Efecto sobre la característica original: Cambio a la semántica de la característica bien definida. Esta característica se marcó como "obsoleta" en C.
8.5.3 funciones dice:
4. La cláusula-declaración-parámetro determina los argumentos que se pueden especificar, y su procesamiento, cuando se llama a la función. [...] Si la cláusula-declaración-parámetro está vacía, la función no toma argumentos. La lista de parámetros (nula) es equivalente a la lista de parámetros vacía.
C99
Como se menciona en C ++ 11, int f()no especifica nada acerca de los argumentos y es obsoleto.
En C, utiliza un vacío en una referencia de función vacía para que el compilador tenga un prototipo y ese prototipo "no tenga argumentos". En C ++, no tiene que decirle al compilador que tiene un prototipo porque no puede omitirlo.
"prototipo" significa la declaración de la lista de argumentos y el tipo de retorno. Digo esto porque "prototipo" me confundió en cuanto a lo que quisiste decir al principio.
Respuestas:
En C :
void foo()
significa "una función quefoo
toma un número no especificado de argumentos de tipo no especificado"void foo(void)
significa "una funciónfoo
que no toma argumentos"En C ++ :
void foo()
significa "una funciónfoo
que no toma argumentos"void foo(void)
significa "una funciónfoo
que no toma argumentos"Al escribir
foo(void)
, por lo tanto, logramos la misma interpretación en ambos idiomas y hacemos que nuestros encabezados sean multilingües (aunque generalmente tenemos que hacer algunas cosas más a los encabezados para hacerlos realmente en varios idiomas; es decir, envolverlos en unextern "C"
si estamos compilando C ++).fuente
void
, entonces podría haber evitado el problema del "análisis más irritante".void foo()
lo tanto, era la única sintaxis para declarar una función. Cuando se introdujeron las firmas, el comité C tuvo que eliminar la ambigüedad del parámetro no de la sintaxis anterior e introducir lavoid foo(void)
sintaxis. C ++ lo tomó por razones de compatibilidad.void foo()
lugar devoid foo(void)
producirá una diferencia funcional? Es decir, he estado usando la versión sin el vacío durante muchos años y no he visto ningún problema, ¿me estoy perdiendo algo?void foo() { if ( rand() ) foo(5); }
compila y ejecuta (causando un comportamiento indefinido a menos que tenga mucha suerte), mientras quevoid foo(void)
con el mismo cuerpo causaría un error de compilación.Me doy cuenta de que su pregunta se refiere a C ++, pero cuando se trata de C, la respuesta se puede encontrar en K&R, páginas 72-73:
fuente
C ++ 11 N3337 borrador estándar
No hay diferencia.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Anexo C "Compatibilidad" C.1.7 Cláusula 8: los declarantes dicen:
8.5.3 funciones dice:
C99
Como se menciona en C ++ 11,
int f()
no especifica nada acerca de los argumentos y es obsoleto.Puede conducir a código de trabajo o UB.
He interpretado el estándar C99 en detalle en: https://stackoverflow.com/a/36292431/895245
fuente
En C, utiliza un vacío en una referencia de función vacía para que el compilador tenga un prototipo y ese prototipo "no tenga argumentos". En C ++, no tiene que decirle al compilador que tiene un prototipo porque no puede omitirlo.
fuente