[C++] signed int

maxwell-cs

Lt. Junior Grade
Registriert
Juli 2007
Beiträge
465
Hi,

nachdem ich heute einen Bug gefixt hab, stelle ich die Ursache (oder einen Teil davon) mal hier vor, vielleicht kommt ja wer drauf :)

Frage:

Wieso können die beiden folgenden Zeilen C++ (C++03) zu verschiedenem Verhalten des restlichen Programms führen, je nachdem, welche Variante gewählt wird?

Code:
typedef int Id;
Code:
typedef signed int Id;

edit: reihenfolge-fix
edit: die auflösung gibt es jetzt weiter unten.
 
Zuletzt bearbeitet:
Default sollte ein int signed sein. daher sollte die zweite Variante dasselbe resultat wie die erste haben.
 
weil du es verkehrt herum definiert hast.

typedef signed int ID;
bzw. äquivalent dazu
typedef int ID;

warum das da oben überhaupt compiliert hat ist ne andere frage.
 
Dachte ich mir auch gerade so, int ist per Definition signed und wenn es z.B. plötzlich vom Compiler her nicht standardmäßig so wäre(sondern unsigned int), bekämst du mit der main Funktion wahrscheinlich Probleme, denn die gibt nunmal signed int zurück und die Betriebssysteme erwarten signed int.
Schließt sich daher aus und du hast deinen Bug wahrscheinlich nicht gefunden ;)

Edit: Dese hat es wohl getroffen, ist mir gerade gar nicht aufgefallen...schande :D
 
sorry, die syntax ist natürlich vertauscht gewesen. ändert aber nichts daran, dass die beiden zeilen zu verschiedenem verhalten führen können :)

der bug war kein bug im compiler oder im betriebssystem, sondern natürlich die falsche der beiden oberen zeilen bzw die unkenntnis darüber, dass sie nicht 100% identisch sind.
 
darf ich fragen um was für ein anderes verhalten es geht?

das dürfte eigentlich nicht zu unterschiedlichem verhalten führen. "signed" ist ein attribut des datentyps "int" und es ist eines der standardattribute.

edit: welcher compiler wurde denn benutzt?
 
xlc

unterschiedliches verhalten hieß in der praxis, dass die eine version später wegen kaputten daten gecrashed ist, während die andere anstandslos durchgelaufen ist.
 
Zuletzt bearbeitet:
erzähl. klingt für mich eher nach einem compiler-bug. denn "signed int" <=> "int", es ist exakt der selbe datentyp.
 
später heute abend.
vielleicht kommt von denen, die etwas später ins forum schauen, noch wer drauf ;)
 
Für mich klingt das nach einem wir bekommen nicht genug Informationen, an den zwei Zeilen wirds nicht liegen. An einem Compilerbug wohl auch kaum.

Ein Klassiker wäre z.b. ein Mehrfachdefinition von Id/ID.
 
dass ich nur diese beiden zeilen angebe, ist durchaus gewollt.

mir war vorher nicht klar, dass sowas passieren kann, und hätte vielleicht später mal an anderer stelle aus der einen variante aus stilgründen die andere gemacht (ohne zu wissen, wo und auf welche weise der typedef benutzt wird - wie ihr jetzt), und wäre mir dabei sicher gewesen, dass das niemals einen unterschied machen kann.
 
Also, daß es jetzt daran gelegen hat, kann ich mir beim besten Willen nicht vorstellen. int beschreibt exakt den gleichen Datentypen wie signed int. Einzig bei char sind signed char, char und unsigned char alle verschiedene Typen.
 
Zuletzt bearbeitet:
Lass dir mal sizeof von den beiden Datentypen ausgeben und schau, ob die die selben MAX-Konstanten erlauben.
Der Standard sagt:
There are five signed integer types : “signed char”, “short int”, “int”, “long int”, and “long long int”.
Er sagt nirgends, dass "int" mit "signed" markiert werden kann, da ein int per default signed ist.
 
Zuletzt bearbeitet:
nullPtr schrieb:
Lass dir mal sizeof von den beiden Datentypen ausgeben und schau, ob die die selben MAX-Konstanten erlauben.
Der Standard sagt:

Er sagt nirgends, dass "int" mit "signed" markiert werden kann, da ein int per default signed ist.

Also meine Kopie sagt was anderes:

Aus Kapitel 3.9.1 Fundamental types, Abschnitt 2:
There are four signed integer types: “signed char”, “short int”, “int”, and “long int.”
 
7.1.5:
—signed or unsigned can be combined with char, long, short, or int.
 
Danke für die Berichtigung.

@antred: In der Tat muss es für C++03 "four" heißen.
 
okay, hier die auflösung:

während ein einfacher "int" per standard ein signed int ist, sieht die situation bei bitfields anders aus:
A bit-field shall have integral or enumeration type (3.9.1). It is
implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or
long bit-field is signed or unsigned.

Code:
typedef int Id;

class ExampleClass {
public:
   ExampleClass();
private:
   Id _id : 16;
};

in diesem beispiel ist nicht festgelegt, ob _id signed oder unsigned ist. während z.b. der gcc sich hier imho konsistent verhält und _id signed macht, macht ein anderer compiler (xlc) ein bitfield unsigned, wenn es nicht explizit als signed markiert ist.

später wurde dann _id mit -1 initialisiert, was natürlich in der unsigned-variante nicht funktioniert.

die folgende variante hingegen verhält sich, wie man es erwartet: _id ist signed.

Code:
typedef signed int Id;

class ExampleClass {
public:
   ExampleClass();
private:
   Id _id : 16;
};
 
Donnerwetter. Wieder was dazugelernt. Ich bin eigentlich ein großer C++-Fan, aber bei Dingen wie diesem kann man schon manchmal an der Komplexität der Sprache und an ihren vielen kaum jemandem bewußten Sonderregeln verzweifeln.
 
Zurück
Oben