2017-05-10 1 views
1

Inspiriert von diesem question, ich habe:Warnung vor nur einem Bitfeld statt an beiden?

#include<stdio.h> 
struct st 
{ 
     int a:1; 
     int b:2; 
}; 

int main() 
{ 
     struct st obj={1, 2}; 
     printf("a = %d\nb = %d\n",obj.a,obj.b); 
} 

und ich bekomme:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
main.c:10:26: warning: implicit truncation from 'int' to bitfield changes value 
     from 2 to -2 [-Wbitfield-constant-conversion] 
     struct st obj={1, 2}; 
         ^
1 warning generated. 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
a = -1 
b = -2 

Ich glaube, ich verstehe, warum beide bitfields versagen, ihre Werte halten (aus dieser answer), aber ich don verstehe nicht, warum der Compiler nur über 2 warnt, statt 1 auch! Irgendwelche Ideen?

ich in meinem Mac bin mit:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -v 
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 8.1.0 (clang-802.0.38) 
Target: x86_64-apple-darwin16.3.0 
Thread model: posix 
InstalledDir: /Library/Developer/CommandLineTools/usr/bin 

In einem alten Linux-System mit gcc Version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5), bekam ich keine ähnliche Warnung.

In einer Debian-Installation, mit GCC-Version 4.9.2 (Debian 4.9.2-10), habe ich keine entsprechende Warnung erhalten!

+0

fyi g ++ 5.1.0 erzeugt die 2 Warnungen, wie erwartet. 2 * 'warning: Überlauf bei impliziter Constant Conversion [-Woverflow]' –

Antwort

1

https://en.wikipedia.org/wiki/Two%27s_complement

Es könnte ein paar Dinge, die passiert sind, vielleicht können einige Experimente helfen.

Erstens könnte es sein, dass gcc intelligent genug ist zu wissen, dass ein einzelnes Bit nicht wirklich positiv oder negativ sein kann, weil es nur das einzelne Bit ist.

Die andere Möglichkeit ist die Reihenfolge, in der gcc einen Ausdruck rückwärts von dem, was Sie denken, auswertet. Einige Compiler bewerten von rechts nach links und in Ihrem Fall, den Fehler rausgeschmissen und gestoppt.

Um zu testen, korrigieren Sie das Bitfeld für b, um eine vorzeichenbehaftete ganze Zahl für '2' zu halten, ohne das Vorzeichenbit umzudrehen (3 Bits sollten funktionieren). Wenn Sie beim Fixieren von 'b' einen Fehler für 'a' erzeugt haben, wissen Sie, dass es sich nur um die Reihenfolge der Compiler-Auswertung handelt.

Wenn das Fixieren von 'b' nicht dazu führt, dass 'a' eine Warnung ausgibt, führt gcc eine interne Optimierung für ein einzelnes Bitfeld aus.

Wenn Sie Ihre Bitfeldtypen in 'uint' ändern, sollten Sie auch die Warnungen korrigieren. In diesem Fall wird einfach das Vorzeichenbit der Darstellung umgedreht.

Glückliche Kodierung.

EDIT Relevant Quellcode: https://github.com/llvm-mirror/clang/blob/master/lib/Sema/SemaChecking.cpp#L8812

+0

Wenn ich 'b' repariere, bekomme ich keine Warnung für' a'. . . Aber +1 für die Idee! – gsamaras

+0

Kühl. Ich würde wahrscheinlich Geld auf gcc mit einer Spezialisierung für einen einzelnen Bit-Fall setzen. In C++ wird dies mit partieller Template-Spezialisierung gemacht, und ich denke, dass * gcc in C++ geschrieben ist. –

+1

Ich fand den Quellcode-Check für Clang hier: https://github.com/llvm-mirror/clang/blob/master/lib/Sema/SemaChecking.cpp#L8812 –

0

int b:2; ist 2 Bit breite Ganzzahl mit Vorzeichen. Nummer 2 (unsigned) wird als 10 in binär dargestellt und da Source int signiert ist, erhalten Sie tatsächlich signierte Nummer im Speicher gespeichert.

Dies ist der Grund, warum Sie diese Warnung erhalten haben.

Werte, die Sie zu 2-Bit signed int speichern können, sind: (-2 = 11, -1 = 10, 0 = 00, 1 = 01)

Grund, warum Sie nicht in beiden Fällen bekommen haben, ist, dass int a:1 nur 1 Bit und Zahlen 1 oder 0, ohne negative Zahlen halten kann.

+0

Danke für die Antwort, aber die Frage ist, warum ich nicht beide Warnungen bekommen habe! :) – gsamaras

+0

Sorry, aktualisierte Antwort oben. – tilz0R

+0

Aber wenn das der Fall ist, würde ich erwarten, dass 1 gedruckt wird. Sehen Sie, die ursprüngliche verknüpfte Frage für mehr bitte. – gsamaras

Verwandte Themen