c++ - todas - tipos de funciones en programacion
Coma omitido en la declaración de funciones variadic en C++ (4)
Actualmente, ambas declaraciones tienen el mismo significado:
int f(int n, ...);
int f(int n ...);
Esto lleva a un problema en el que las siguientes dos declaraciones son legales, pero tienen significados muy diferentes:
template <class... T> void f(T...); // function template with parameter pack template <class T> void f(T...); // variadic function
Una vez que C ++ 11 introdujo plantillas variadic, es mucho más probable que la segunda declaración sea un error del programador en lugar de omitir la coma. Como resultado, hubo una propuesta para eliminar el último del idioma ( P0281 ), pero aparentemente fue rejected .
Estoy acostumbrado a declarar funciones variadas como esta:
int f(int n, ...);
Al leer el lenguaje de programación C ++ encontré que las declaraciones en el libro omiten la coma:
int f(int n...); // the comma has been omitted
Parece que esta sintaxis es específica de C ++ ya que obtengo este error cuando intento compilarlo usando un compilador de C:
test.c:1:12: error: expected '';'', '','' or '')'' before ''...'' token int f(int n...);
¿Hay alguna diferencia entre escribir int f(int n, ...)
e int f(int n...
)?
¿Por qué se agregó esta sintaxis a C ++?
Como recuerdo de la época, C ++ de hecho definió signos de función variadic como usted nota. Más tarde, el lenguaje C de rápida evolución (en el viaje de K & R a ANSI) introdujo prototipos o declaraciones de funciones de estilo nuevo que también declaraban parámetros dentro de parens después del nombre de la función. Pero, con dos diferencias notables: la coma antes de las elipsis, y la necesidad de la abominación de (void)
para indicar una lista de parámetros vacía (para preservar la compatibilidad con versiones anteriores de los parens vacíos como una declaración de estilo antiguo ).
Al mirar a través de mis archivos, encuentro que la edición original de C ++ Programming Language "reimpreso con correcciones de julio de 1987" muestra:
argument-declaration-list:
arg-declaration-list opt ...
opt
arg-declaration-list:
arg-declaration-list ,
argument-declaration
argumento-declaración
No hay forma de aceptar la coma ahora opcional. Tenga en cuenta que arg-declaration-list está separado por comas y no se cuelga para proporcionar una coma después de la lista y antes de la siguiente (diferente) cosa.
Esta es la forma más natural de escribir esto. Si desea una coma, necesita explícitamente , ...
en la primera producción, como dos tokens distintos (posiblemente separados por espacios en blanco).
A medida que progresaron los esfuerzos de C para lograr una estandarización adecuada, los compiladores de C ++ también comenzaron a aceptar las versiones C para permitir el uso fácil de los archivos de encabezado estándar de C.
¿Por qué los diseñadores de C agregaron la coma cuando implica un papel gramatical menos sensato de las elipses como marcador de posición de parámetro falso? Nunca me enteré.
Con int f(int n, ...);
e int f(int n...);
, como puedes ver , ambos , ...
y ...
tienen el mismo significado. La coma es opcional.
Pero esta int printz(...);
es válido en C++
mientras int printz(,...);
no es (al menos un parámetro nombrado debe aparecer antes del parámetro de puntos suspensivos). Es por eso que puede tener solo (...)
, aunque los argumentos pasados a dicha función no son accesibles.
De acuerdo con el § 8.3.5.4 del estándar C ++ ( borrador actual ):
Donde sintácticamente correcto y donde "..." no es parte de un declarador-abstracto, ", ..." es sinónimo de "...".
En resumen, en C ++ ...
(puntos suspensivos) es un operador por derecho propio, por lo que puede usarse sin la coma, pero el uso de la coma se conserva para compatibilidad con versiones anteriores.