programacion ppt enum c++ c typedef

c++ - enum - typedef ppt



¿El typedef-name es opcional en una declaración typedef? (3)

Es una sintaxis degenerada que está permitida pero no proporciona ningún beneficio. La mayoría de los compiladores modernos pueden ser provocados para que emitan una advertencia al respecto; por defecto, no pueden. Sin el nombre typedef, la palabra clave typedef es superflua; en su ejemplo, es completamente equivalente a:

enum test { one };

Otro lugar donde puede ocurrir es con una estructura:

typedef struct SomeThing { int whatever; };

Esto es equivalente a:

struct SomeThing { int whatever; };

Tenga en cuenta que typedef es oficialmente (o sintácticamente) un ''especificador de clase de almacenamiento'', como static , extern , auto y register .

C estándar

En ISO / IEC 9899: 1999 (ese es el estándar C), encontramos:

§6.7 Declaraciones

Sintaxis

declaración :

declaradores de especificación init-declarator-list opt ;

declaradores de especificación :

especificación de especificación de clase de almacenamiento especificadores de especificación

especificación de tipo especificación de especificación de especificación

Los especificadores de declaración de calificadores de tipo optan

especificación de la función especificación de los especificadores opt

init-declarator-list :

declarador de inicio

init-declarator-list , init-declarator

init-declarator :

declarador

declarador = inicializador

Y (según lo solicitado):

§6.7.1 Especificadores de clase de almacenamiento

Sintaxis

especificador de clase de almacenamiento:

typedef

extern

static

auto

register

Si realiza un seguimiento a través de esa sintaxis, hay muchas posibilidades degeneradas, y lo que mostró es solo una de las muchas.

Estándar C ++

Es posible que C ++ tenga reglas diferentes.

En ISO / IEC 14882: 1998 (el estándar original de C ++), encontramos en §7.1.1 ''Especificadores de la clase de almacenamiento'' que C ++ no trata a typedef como una clase de almacenamiento; la lista agrega mutable y excluye typedef . Por lo tanto, la especificación gramatical de typedef en C ++ es definitivamente diferente de la especificación en C.

§7 Declaraciones

Las declaraciones especifican cómo deben interpretarse los nombres. Las declaraciones tienen la forma.

declaración-seq:

declaración

declaración declaración-seq

declaración:

declaración de bloque

definición de la función

declaración de plantilla

instanciación explícita

especialización explícita

vinculación-especificación

definición del espacio de nombres

declaración de bloque:

declaración simple

asm-definition

definición de alias de espacio de nombres

declaración de uso

directiva de uso

declaración simple:

decl-specifier-seq opt init-declarator-list opt ;

...

¶5 Si el decl-specifier-seq contiene el especificador typedef , la declaración se denomina declaración typedef y se declara que el nombre de cada declarador de init-declarator es un nombre typedef, sinónimo de su tipo asociado (7.1.3).

§7.1 Especificadores [dcl.spec]

Los especificadores que se pueden utilizar en una declaración son

decl-especificador:

especificador de clase de almacenamiento

especificador de tipo

especificador de funciones

friend

typedef

decl-specifier-seq:

decl-specifier-seq opt

decl-especificador

§7.1.1 Especificadores de clase de almacenamiento [dcl.stc]

especificador de clase de almacenamiento:

auto

register

static

extern

mutable

§7.1.2 Especificadores de funciones [dcl.fct.spec]

especificador de función:

inline

virtual

explicit

§7.1.3 El especificador typedef [dcl.typedef]

Las declaraciones que contienen el especificador decl- typedef declaran identificadores que pueden usarse posteriormente para nombrar tipos fundamentales (3.9.1) o compuestos (3.9.2). El especificador typedef no se utilizará en una definición de función (8.4), y no se combinará en un especificador de decl seq con ningún otro tipo de especificador excepto un especificador de tipo.

typedef-name:

identificador

...

En un ámbito determinado, se puede utilizar un especificador typedef para redefinir el nombre de cualquier tipo declarado en ese ámbito para hacer referencia al tipo al que ya hace referencia. [Ejemplo:

typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I;

—En ejemplo]

§7.1.4 El amigo especificador [dcl.friend]

El especificador amigo se utiliza para especificar el acceso a los miembros de la clase; ver 11.4.

§7.1.5 Especificadores de tipo [dcl.type]

tipo-especificador:

especificador de tipo simple

especificador de clase

enum-specifier

especificador de tipo elaborado

calificador cv

Dado que §7, ¶5 dice que los nombres typedef provienen del init-declarator y el init-declarator-list está etiquetado como '' opt '', creo que eso significa que el nombre typedef puede omitirse en C ++, al igual que en C.

Me sorprendió bastante cuando vi el siguiente código compilado sin errores ni advertencias en g ++ - 4.2:

typedef enum test { one };

Mi suposición era que si utilizaba la palabra clave typedef , se requeriría un identificador adicional como en:

typedef enum test { one } test;

Como ya se mencionó, g ++ - 4.2 lo acepta sin siquiera una advertencia. Clang ++ 3.0 advierte " warning: typedef requiere un nombre ", Comeau también advierte " warning: statement requiere un nombre typedef ", y g ++ - 4.6 informa: " warning: ''typedef'' se ignoró en esta declaración ".

No he podido identificar en qué parte del estándar está permitido, y me parece un poco confuso que dos de los compiladores adviertan que es necesario , ¿no debería ser un error si se requiere typedef-name pero no está presente?

ACTUALIZACIÓN : he registrado C con los mismos compiladores. Clang y comeau producen la misma salida, gcc da una advertencia: " advertencia: especificador de clase de almacenamiento inútil en declaración vacía ", lo que parece aún más confuso.

ACTUALIZACIÓN : He comprobado la eliminación del nombre de la enumeración y los resultados son los mismos:

typedef enum { one };

De manera similar con una estructura nombrada:

typedef struct named { int x };

Pero no con una estructura sin nombre, en cuyo caso el código fue rechazado en g ++ (4.2 / 4.6) con " error: falta el nombre de tipo en typedef-declaraciones ", gcc (4.2 / 4.6) dio una advertencia: " advertencia: estructura sin nombre / unión que no define instancias ", clang ++" advertencia: la declaración no declara nada ", comeau" error: la declaración requiere un tipo de nombredef "


Lo único que pude encontrar fue lo siguiente en el estándar C ++ 03 §7.1.3 [dcl.typedef] p1 :

typedef-name:

  • identificador

Un nombre declarado con el especificador typedef se convierte en un typedef-name .

Observe el opt después del identificador faltante, que indica, al menos para mí, que se necesita un identificador para el typedef-name . Es extraño que todos los compiladores probados (silenciosamente) lo acepten.

Editar : Después de la respuesta de @Jonathan, encontré lo siguiente en el mismo estándar que el anterior:

decl-especificador :

  • especificador de clase de almacenamiento
  • especificador de tipo
  • especificador de funciones
  • friend
  • typedef

Como puede verse, proporciona un caso adicional para typedef y la lista de especificadores de clase de almacenamiento confirma esto:

especificador de clase de almacenamiento:

  • auto
  • register
  • static
  • extern
  • mutable

Entonces, estamos tan despistados como antes en el caso de C ++.


Realmente se ve como una diferencia C vs. C ++, para mí. C ++ tipifica implícitamente estructuras y uniones a sus etiquetas; así que agregar el typedef es superfluo, pero no es un error. No sé si esto también funciona para las enumeraciones.

Lo que hay que hacer a continuación es ver qué definiciones de variables están permitidas después de estas declaraciones.

enum test etest; test etest2; struct named snamed; named snamed2;