Unsigned
-
Konrad Rudolph schrieb:
TactX schrieb:
Das rechtsschieben von negativen Integern ist nicht festgelegt.
Das ist mir klar, hat aber mit der Problematik nichts zu tun.
Doch, hat es. Und zwar genau deswegen. Das Shiften von negativen Werten ist implementationsspezifisch. Daher weisst du nicht, wie ein Compiler hier shiftet. Wenn man auf Bitebene arbeitet, braucht man aber zuverlässige Ergebnisse. Was anderes wäre es, wenn C++ festlegen würde, dass generell logisch geshiftet wird. Warum das nicht gemacht wurde, da fragst du am besten mal beim ISO Komitee nach.
Konrad Rudolph schrieb:
ten schrieb:
für alles was sich besser mit 'natürlichen zahlen' darstellen darstellen lässt, nimmt man lieber 'unsigned'.
Genau das überzeugt mich ja gerade nicht. Man spart in Deinem Beispiel zwar eine triviale Abfrage, trotzdem könnte man die Funktion aber falsch aufrufen:
wie_weit_komme_ich(-1);Das eigentliche Problem hier (Modellieren einer natürlichen Zahl) hat man nicht gelöst, man hat lediglich zwei Codezeilen gespart.
Was man jedoch gerne mitnimmt. Jede Vereinfachung ist willkommen. Und für dich mag das zwar trivial erscheinen. Aber gerade Sprunganweisungen, die in kurzen Sequenzen sehr häufig abgearbeitet werden, können ordentlich auf die Performance drücken. Zudem ist es einfach sauberer. Wenn ein negativer Wert nicht plausibel ist, dann soll auch keiner im verwendeten Typ gespeichert werden können. Übrigens, ein Compiler mit pedantischer Fehlerprüfung sollte hier zumindest eine Warnung ausspucken. GCC macht das zB mittels -Wconversion.
Wenn überhaupt, dann stellt sich die Frage in C++ nicht nach dem unsigned. Sondern warum man eine explizite Aufteilung in signed und unsigned Typen macht.
-
groovemaster schrieb:
Wenn überhaupt, dann stellt sich die Frage in C++ nicht nach dem unsigned. Sondern warum man eine explizite Aufteilung in signed und unsigned Typen macht.
Ja, so meinte ich das eigentlich auch.
Wobei ich die Antworten in dem Thread schon ganz gut finde.
-
Konrad Rudolph schrieb:
So, bisher hat aber immernoch niemand in diesem Thread die Anfangsfrage beantwortet, nämlich, wofür 'unsigned' denn nun gut ist. Ich bitte darum, das noch zu tun, die Antwort würde mich nämlich auch interessieren. Bisher kenne ich keinen guten Grund für 'unsigned'.
Es gibt mehrere Gründe
a) Die Ausdrucksstärke des Codes wird erhöht
b) Überlauf bei Signed-Variablen ist undefiniert
c) Zahlreiche potentielle Probleme und Sicherheitslücken
(wer sieht den Fehler?)void foo(int n) { char buffer[SIZE]; // ... if(abs(n) >= SIZE) throw out_of_range(); do_sth(buffer[abs(n)]); }d) ...
(oder sagen wir mal, die Fragestellung muss man andersrum angehen: "Warum sollte man auf unsigned verzichten?")
-
rüdiger schrieb:
(oder sagen wir mal, die Fragestellung muss man andersrum angehen: "Warum sollte man auf unsigned verzichten?")
Was mich eher interessieren würde:
Sollten unsigned-Datentypen fester Bestandteil einer (neuen) modernen, effizienten Programmiersprache sein (außer für Interop-Zwecke)?
Bisher dachte ich, die Antwort darauf laute "nein", so langsam lasse ich mich aber gerade vom Gegenteil überzeugen.
-
rüdiger schrieb:
(wer sieht den Fehler?)
if(abs(n) >= SIZE) ...müsste sein:
if(abs(n) > SIZE)hat aber mit dem eigentlichen thema hier nix zu tun...

-
ten schrieb:
rüdiger schrieb:
(wer sieht den Fehler?)
if(abs(n) >= SIZE) ...müsste sein:
if(abs(n) > SIZE)hat aber mit dem eigentlichen thema hier nix zu tun...

ne
int a[5]; a[5]=10; // <-- das wäre ja auch ein Overflow
-
rüdiger schrieb:
int a[5]; a[5]=10; // <-- das wäre ja auch ein Overflowdas meine ich ja auch...

-
ten schrieb:
rüdiger schrieb:
int a[5]; a[5]=10; // <-- das wäre ja auch ein Overflowdas meine ich ja auch...

nö, davor ist es ja abgesichert, das n == SIZE
-
ach ja, mist

so ist's besser...void foo (int n) { char buffer[SIZE]; int a = abs(n) if(a < SIZE) do_sth(buffer[a]); }abs sorgt dafür, dass a nicht negativ wird.
ok, dein beispiel ist sehr wohl relevant für dieses thema.
hat mich voll verwirrt, kein vernünftiger mensch nimmt für sowas einen 'signed' typ
-
der Code hat immer noch den Fehler, auf den ich hinaus will

-
rüdiger schrieb:
der Code hat immer noch den Fehler, auf den ich hinaus will

wieso

wenn a<SIZE und a=abs(n) dann heisst das doch 0<=a<SIZE
oder nicht?
-
ten schrieb:
rüdiger schrieb:
der Code hat immer noch den Fehler, auf den ich hinaus will

wieso

wenn a<SIZE und a=abs(n) dann heisst das doch 0<=a<SIZE
oder nicht?Die Frage ist ja, ob abs in jedem Fall einen positiven Wert zurück gibt. Was ist das Ergebnis von abs(INT_MIN)?

-
rüdiger schrieb:
Was ist das Ergebnis von abs(INT_MIN)?

doch wohl kein negativer wert, oder?
-
ten schrieb:
rüdiger schrieb:
Was ist das Ergebnis von abs(INT_MIN)?

doch wohl kein negativer wert, oder?
oder?
-
rüdiger schrieb:
ten schrieb:
rüdiger schrieb:
der Code hat immer noch den Fehler, auf den ich hinaus will

wieso

wenn a<SIZE und a=abs(n) dann heisst das doch 0<=a<SIZE
oder nicht?Die Frage ist ja, ob abs in jedem Fall einen positiven Wert zurück gibt. Was ist das Ergebnis von abs(INT_MIN)?

Ich vermute mal INT_MAX-1
-
ten schrieb:
rüdiger schrieb:
Was ist das Ergebnis von abs(INT_MIN)?

doch wohl kein negativer wert, oder?
Es ist Implementierungsabhängig. Aber auf vielen Plattformen dürfte abs(INT_MIN) == INT_MIN sein.
Man sieht also, das es nicht ganz ungefährlich ist, wenn man signed Variablen benutzt, wo man unsigned benutzen sollte.
(Ganz zu schweigen von dem Problem, das man mit size_t ein fertiges typedef für Größenangaben hat und keineswegs gelten muss sizeof(size_t) == sizeof(int) (siehe zB AMD64))
-
EDIT: Totaler Unsinn.
-
Hier ist noch mal ein Text, der darauf eingeht, wie man Integer-Probleme (unter anderem auch Signed/Unsigned-Probleme) zum Exploiten von Programmen benutzen kann http://www.phrack.org/archives/60/p60-0x0a.txt