2009-04-16 15 views
10

Ich habe eine Struktur ohne Elemente (für den Moment) und ich würde gerne wissen, ob es möglich ist, um die Warnung zu unterdrücken ich:Leere Struktur in C

warning: struct has no members 

Ist es möglich, ein Mitglied hinzufügen und behalten Sie die sizeof die Struktur Null? Irgendeine andere Lösung?

+0

Warum brauchen Sie die Größe auf Null? –

+1

Weil ich eine private Schnittstelle habe (in der ich meine Struktur von null Größe habe, weil ich keine bestimmte Funktionalität implementiere) und eine Ã-ffentliche Schnittstelle, wo einige meiner privaten Strukturen undurchsichtig werden und nur die gleiche Größe wie private haben müssen. – claf

+0

Mein Build-System überprüft die private Strukturgröße und erstellt die öffentliche Struktur mit einem "char _opaque [SIZEOF_PRIVATE_STRUCT]". – claf

Antwort

18

In c das Verhalten einer leeren Struktur Compiler abhängig Vergleich C++, wo sie Teil der spec (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.

in C ist, ist es eher trübes, da der C99-Standard hat eine Sprache, die impliziert, dass wirklich leere Strukturen nicht erlaubt sind (siehe TrayMan's Antwort), aber viele Compiler erlauben es (zB gcc).

Da dies compilerabhängig ist, ist es unwahrscheinlich, dass Sie in diesem Fall wirklich portablen Code erhalten. Solche nicht portablen Möglichkeiten, die Warnung zu unterdrücken, sind vielleicht die beste Wahl.

+0

Es gibt also keine Möglichkeit, diese Warnung portabel zu vermeiden? (Sonst dann einen Compiler spezifischen # Pragma mit #ifdef zum Beispiel) – claf

+0

Darüber hinaus für GCC Diagnostic Pragmas: "Während es syntaktisch gültig ist, diese Pragmas irgendwo in Ihren Quellen zu platzieren, ist der einzige unterstützte Speicherort für sie vor irgendwelchen Daten oder Funktionen sind definiert. " Was bedeutet für mich, ich kann JUST diese Warnung nicht unterdrücken, habe ich Recht? – claf

+1

Die Frage ist über C, nicht C++. –

1

Wenn Sie sich nicht „zu streng“ Einhaltung erfordert, könnte erhalten Sie mit diesem weg:

struct empty { 
    char nothing[0]; 
}; 

Dies ist ein GCC extension, though.

ich irgendwie hatte gehofft, dass ich in der Lage sein würde, die C99-Funktion „flexible Arrays“ genannt zu verwenden, wie dies erklärt:

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

aber das funktioniert nicht; sie erfordern, dass es mindestens ein normales Strukturelement gibt, sie können nicht das einzige Mitglied sein.

+1

Na ja, GCC akzeptiert sowieso leere Strukturen ... Scheinbar mit der Größe 0. Andererseits wird es auf leeren Strukturen ebenso wie bei dieser Lösung scheitern, wenn Pedantic eingeschaltet wird (pedantische Warnungen + Verwandlung in Fehler). – Aconcagua

4

C99 standard ist nicht ganz eindeutig auf diese haben, aber scheint zu sagen, dass eine leere Struktur nicht-Null haben sollte Größe.

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?

Nope. FWIW, C++ erlaubt leere Strukturen, aber die Größe von() ist für eine leere Struktur immer ungleich Null.

Any other solution?

Keine einfachen. Es ist erwähnenswert, dass leere Strukturen in C nur etwas unterstützt und in C99 nicht erlaubt sind.

Empty Strukturen werden in C++ unterstützt, aber verschiedene Compiler implementieren sie mit unterschiedlichen Ergebnissen (für sizeof und struct offsets), besonders wenn Sie anfangen, Vererbung in den Mix zu werfen.

18

wenn Sie nur die Struktur Symbol für das Gießen und Funktionsargumente müssen dann nur:

typedef struct _Interface Interface; 

dies das Symbol für einen unverständlichen Typ erstellen.

+2

DANKE! Ich versuche zu testen Mein Projekt auf verschiedenen Compilern, und bekam einen seltsamen Kompilierfehler in Borland C++. Es sagte mir, dass diese Funktion, die eine leere Struktur verwendete, kein Mitglied der Klasse war, für die sie deklariert wurde. Ich habe versucht, das Problem zu lösen Die letzten 2,5 Stunden Es stellt sich heraus, ich musste nur die Klammern loswerden, wenn ich die leere Struktur erklärte, wie du es zeigst, und es funktioniert gut. Sohn eines b ----. Danke !! – leetNightshade

10

Technisch ist dies nicht einmal gültig C.

TrayMan ein wenig war in seiner Analyse aus, ja 6.2.6.1 sagt:

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.

aber das Krawatte mit 6.2.5-20, die sagt:

— 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.

und jetzt können Sie schlussfolgern, dass Strukturen werden ein oder mehrere Bytes sein weil sie können nicht leer sein. Der Code gibt Ihnen eine Warnung, während der gleiche Code tatsächlich scheitern auf Microsoft Visual Studio mit einem Fehler zu kompilieren:

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

So die kurze Antwort ist nein, es ist kein tragbarer Weg ist, zu vermeiden, diese Warnung, weil sie Ihnen sagt, dass Sie die C-Standards verletzen. Sie müssen eine Compiler-spezifische Erweiterung verwenden, um es zu unterdrücken.

0
struct zero_information { int:0; }; 

Das obige Codefragment einen nicht -Nullsignal Wert von sizeof(struct zero_information) ergeben wird, aber es könnten Ihnen, was Sie für 100% des gesamten Speichers helfen, suchen, der für sich zugeordnet ist, Polsterung (nur zugänglich durch Hacks, obwohl ich mich nicht von Kopf bis Fuß erinnern kann, ob das Padding nicht definiert ist.

+0

Alle gleich wie in meinem Kommentar für die Lösung von Unwind. – Aconcagua