2009-04-16 20 views
10

que tiene una estructura que no tiene miembros (por el momento) y me gustaría saber si es posible suprimir la advertencia consigo:estructura vacía en C

warning: struct has no members 

¿Es posible agregar un miembro y mantener el sizeof la estructura cero? ¿Alguna otra solución?

+0

¿Por qué necesita que el tamaño sea cero? –

+1

Porque tengo una interfaz privada (en la que tengo mi estructura de tamaño cero porque no implemento una cierta funcionalidad) y una interfaz pública donde algunas de mis estructuras privadas se vuelven opacas y solo tienen que tener el mismo tamaño que las privadas. – claf

+0

Mi sistema de compilación verifica el tamaño de la estructura privada y crea la estructura pública con un "char _opaque [SIZEOF_PRIVATE_STRUCT]". – claf

Respuesta

18

En c el comportamiento de una estructura de vacío es dependiente compilador frente C++ donde es parte de la especificación (explanations here)

C++
A class with an empty sequence of members and base class objects is an empty class. Complete objects and member subobjects of an empty class type shall have nonzero size.

en C es más bien más turbia ya que el estándar c99 tiene algún lenguaje que implica que las estructuras verdaderamente vacías no están permitidas (ver la respuesta de TrayMan) pero muchos compiladores sí lo permiten (ej. gcc).

Como esto depende del compilador, es poco probable que obtenga un código realmente portátil en este caso. Como tales formas no portátiles para suprimir la advertencia puede ser su mejor opción.

+0

Entonces, ¿no hay forma de evitar portables esta advertencia? (Además de tener un compilador específico #pragma usando #ifdef por ejemplo) – claf

+0

Además, para GCC Pragmas de diagnóstico: "Además, aunque es sintácticamente válido colocar estos pragmas en cualquier lugar de sus fuentes, la única ubicación admitida para ellos es antes de cualquier dato o las funciones están definidas ". Lo que significa para mí que no puedo suprimir JUST esta advertencia, ¿estoy en lo cierto? – claf

+1

La pregunta es sobre C, no C++. –

1

Si usted no está requiriendo "demasiado estricta" la adhesión, es posible que salgas con la tuya:

struct empty { 
    char nothing[0]; 
}; 

Esta es una GCC extension, sin embargo.

Yo tenía la esperanza de que sería capaz de utilizar la función C99 llamados "arreglos flexibles", declaró así:

struct empty99 
{ 
    char nothing[]; // This is a C99 "flexible array". 
}; 

pero eso no funciona; requieren que haya al menos un miembro de estructura normal primero, no pueden ser el único miembro.

+1

Bueno, GCC acepta estructuras vacías de todos modos ... Aparentemente con un tamaño de 0. Por otro lado, fallará en las estructuras vacías, así como con esta solución si se activa pedantic (advertencias pedantes + convirtiéndolas en errores). – Aconcagua

4

C99 standard es algo ambiguo sobre esto, pero parece decir que una estructura vacía debe tener distinto de cero tamaño.

6.2.6.1 Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.

2

Is it possible to add a member and keep the sizeof the struct zero?

Nop. FWIW, C++ permite estructuras vacías, pero el sizeof() siempre es distinto de cero para una estructura vacía.

Any other solution?

No es nada fácil. Vale la pena señalar que las estructuras vacías solo se admiten algo en C y no se permiten en C99.

Las estructuras vacías son compatibles con C++, pero los diferentes compiladores las implementan con resultados variables (para el tamaño y los desplazamientos estructurales), especialmente una vez que comienzas a tirar la herencia a la mezcla.

18

si sólo tiene el símbolo estructura de fundición y argumentos de función luego simplemente:

typedef struct _Interface Interface; 

esto creará el símbolo de un tipo opaco.

+2

¡GRACIAS! Estoy intentando probar mi proyecto en diferentes compiladores, y estaba obteniendo un raro error de compilación en Borland C++. Me decía que esta función que usaba una estructura vacía no era miembro de la clase en la que estaba declarada. He estado tratando de resolver el problema las últimas 2.5 horas. Resulta que todo lo que tuve que hacer fue deshacerme de los corchetes al declarar la estructura vacía, como se muestra, y funciona bien. Hijo de un b ---- ¡Gracias! – leetNightshade

10

Técnicamente esto ni siquiera es válido C.

TrayMan era un poco en su análisis, sí 6.2.6.1 dice:

Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, the number, order, and encoding of which are either explicitly specified or implementation-defined.

pero que atar con 6.2.5-20, que dice:

— A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type.

y ahora se puede concluir que las estructuras van a tener uno o más bytes porque no pueden estar vacíos. Su código que está dando una advertencia, mientras que el mismo código en realidad dejar de compilar en Visual Studio de Microsoft con un error:

error C2016: C requires that a struct or union has at least one member

Así que la respuesta corta es no, no hay una manera portátil para evitar esta advertencia, porque te dice que estás violando los estándares de C. Tendrá que usar una extensión específica del compilador para suprimirlo.

0
struct zero_information { int:0; }; 

El fragmento de código anterior no dará lugar a una valor -cero de sizeof(struct zero_information), pero podría ayudar a obtener lo que busca como el 100% de todo el almacenamiento asignado para ello, es el relleno (sólo accesible a través de hacks, aunque no recuerdo de lo más caliente si acceder al padding es un comportamiento indefinido).

+0

Todo el mismo como en mi comentario para la solución de desenrollar. – Aconcagua