PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++] Zur Compilezeit bestimmen, ob char signed ist



BLUESCREEN3D
31-03-2006, 22:09
Ich will eine Variable vom Typ char mit einem int oder unsigned int vergleichen (==, !=, <, > usw.).
Je nachdem, ob char nun signed char oder unsigned char entspricht gibt es aber bei einer der beiden Möglichkeiten eine Warnung.
Deshalb will ich zur Compilezeit bestimmen, was char ist, damit ich den nicht passenden Vergleich weglassen kann.

Ich dachte, ich könnte das durch Funktionsüberladung lösen, wobei ich die Funktion einmal mit signed char und einmal mit unsigned char schreibe, aber der Compiler will entweder nur eine der möglichen char-Funktionen oder alle drei...

bischi
31-03-2006, 22:13
Ähm - sind meine C++-Kenntnisse so schlecht? Was ist unsigned-char? Ich dachte immer ein char sei ein Zeichen - welches je nach Codierung etwa einer Zahl zwischen 0 und 255 entspricht? Kann das signed sein?

MfG Bischi

PS: Kannst du nicht einfach char nehmen und danach nen Type-Cast (explizit) machen?

BLUESCREEN3D
31-03-2006, 22:42
Was ist unsigned-char? Ich dachte immer ein char sei ein Zeichen - welches je nach Codierung etwa einer Zahl zwischen 0 und 255 entspricht? Kann das signed sein?
Ja, es gibt da drei verschiedene Datentypen: char, signed char (-128 bis 127) und unsigned char (0 bis 255). Wobei char entweder das gleiche wie signed char oder unsigned char ist.


PS: Kannst du nicht einfach char nehmen und danach nen Type-Cast (explizit) machen?
Wohin soll ich casten, wenn ich nicht weiß, ob char signed oder unsigned ist?

bischi
01-04-2006, 08:50
Kannst das Ding ja zuerst nach unsigned char casten - dann hast du auf jeden Fall ne Zahl zwischen 0 und 255. (Ich nehm mal an, dass die signed-Variante einfach um 128 verschoben ist.) Danach kannst du mit int vergleichen.

MfG Bischi

locus vivendi
01-04-2006, 11:09
Ich will eine Variable vom Typ char mit einem int oder unsigned int vergleichen (==, !=, <, > usw.).
Je nachdem, ob char nun signed char oder unsigned char entspricht gibt es aber bei einer der beiden Möglichkeiten eine Warnung.
Deshalb will ich zur Compilezeit bestimmen, was char ist, damit ich den nicht passenden Vergleich weglassen kann.
Das geht sowohl mit <limits> als auch <limits.h>. In <limits.h> wird z.B. CHAR_MIN definiert. CHAR_MIN ist entweder 0, dann ist "char" ohne Vorzeichen, oder CHAR_MIN ist gleich SCHAR_MIN (also negativ), dann ist char signed. Und mit <limits> kannst du testen "std::numeric_limits<char>::is_signed". Eine dieser Methoden sollte für deine Zwecke eigentlich ausreichen.

BLUESCREEN3D
01-04-2006, 16:38
Kannst das Ding ja zuerst nach unsigned char casten - dann hast du auf jeden Fall ne Zahl zwischen 0 und 255.
Damit würde aber der Vergleich sinnlos werden...
Wenn man z.b. -1 als char hat und char signed ist und das dann nach unsigned char castet, dann ist das 255 und wenn man auf dem Weg vergleicht, ob -1<0, dann ist das unwahr, weil nach dem Cast mit 255<0 gerechnet wird.


Und mit <limits> kannst du testen "std::numeric_limits<char>::is_signed".
Das bringt mir nichts, weil es eine Laufzeit-Prüfung ist - auch wenn diese im Endeffekt vom Compiler wegoptimiert wird kann ich die nicht im Präprozessor verwenden. Allerdings fällt mir nun auf, dass ich den Präprozessor dafür eigentlich nicht brauche, wenn der Compiler das optimiert... Kann man sich darauf verlassen, dass jeder C++-Compiler Dinge wie "if (false)" wegoptimiert?


Das geht sowohl mit <limits> als auch <limits.h>. In <limits.h> wird z.B. CHAR_MIN definiert. CHAR_MIN ist entweder 0, dann ist "char" ohne Vorzeichen, oder CHAR_MIN ist gleich SCHAR_MIN (also negativ), dann ist char signed.
thx, genau sowas habe ich gesucht :)

locus vivendi
01-04-2006, 17:04
Ich freue mich, dass ich dir helfen konnte.


Zitat von locus vivendi
Und mit <limits> kannst du testen "std::numeric_limits<char>::is_signed".
Das bringt mir nichts, weil es eine Laufzeit-Prüfung ist - auch wenn diese im Endeffekt vom Compiler wegoptimiert wird kann ich die nicht im Präprozessor verwenden. Allerdings fällt mir nun auf, dass ich den Präprozessor dafür eigentlich nicht brauche, wenn der Compiler das optimiert... Kann man sich darauf verlassen, dass jeder C++-Compiler Dinge wie "if (false)" wegoptimiert?
Allerdings irrst du dich hier. std::numeric_limits<char>::is_signed ist eine Compile-Time-Konstante, laut Abschnitt 18.2.1 "Numeric limits" im Standard:
"For all members declared static const in the numeric_limits template, specializations shall define these values in such a way that they are usable as integral constant expressions."
Und is_signed ist als "static const bool" deklariert. (Ist übrigens auch im aktuellen Draft des Standards zu finden.)

BLUESCREEN3D
01-04-2006, 19:26
Stimmt, ich hatte mir angeguckt, wie is_signed bestimmt wird (in dem Fall über (char)-1<0).

Jedenfalls meinte ich, dass man folgendes nicht schreiben kann:

#if std::numeric_limits<char>::is_signed

Joghurt
02-04-2006, 14:48
Ja, das schreibt man auch als
if (std::numeric_limits<char>::is_signed) { ..} else {...}der Compiler optimiert das schon weg.
Ebenso ist
const int FOO=42; ... a=FOO;bei Optimierung identisch mit der alten #define-Methode. Im Allgemeinen brauchst du den Präprozessor in C++ nur noch für #includes und #ifdefs