Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Vergleich signed unsigned

1 view
Skip to first unread message

iwl

unread,
Nov 5, 2009, 9:01:45 PM11/5/09
to
Hallo,

wie bekommt man Warnungen für Vergleich signed/unsigned weg und werden
diese korrekt ausgeführt, sprich wenn signed negativ, dann ist es eben
kleiner als die unsigned Variable.
Was ist der Grund für die Warnung?

iwl

unread,
Nov 5, 2009, 9:19:35 PM11/5/09
to
Hierzu passt auch:

int test=0xFFFFFFFF;

hier bekomme ich keine Warnung, hätte aber sogar gerne einen Fehler.

Rene Möhring

unread,
Nov 6, 2009, 2:27:22 AM11/6/09
to
iwl schrieb:
> Hallo,
>
> wie bekommt man Warnungen f�r Vergleich signed/unsigned weg und werden
> diese korrekt ausgef�hrt, sprich wenn signed negativ, dann ist es eben

> kleiner als die unsigned Variable.
> Was ist der Grund f�r die Warnung?
Einfach passende Datentypen verwenden. Der Grund f�r die Warnung ist,
da� sich die Wertebereiche unterscheiden.

Thomas Koller

unread,
Nov 6, 2009, 3:11:06 AM11/6/09
to
iwl <Ingo...@gmx.de> wrote:
> wie bekommt man Warnungen f�r Vergleich signed/unsigned weg

Warnungen sind Compilersache, es kann dabei jeder handhaben wie er will
und in der Praxis wirst von verschiedenen Compilern verschiedene
Warnungen bekommen. Nicht alle warnen bei Vergleich signed/unsigned.

Meistens bekommt man die Warnung mit einem cast weg.

Am besten ist es meistens nat�rlich gleich von vornherein gleiche
Typen zu verwenden und nicht �pfel mit Birnen zu vergleichen. ;-)
(Ok, der Vergleich ist �bertrieben)

> und werden diese korrekt ausgef�hrt,

Kommt drauf an was du unter "korrekt" verstehst.

> sprich wenn signed negativ, dann ist es eben
> kleiner als die unsigned Variable.

Dazu musst du die zwei Werte in einen passenden Typ umwandeln,
der "Platz" genug f�r beide Werte hat, bzw. �berl�ufe bei der
Konvertierung entsprechend behandeln. Oder einfach selbst vor
dem Vergleich auf negative Werte abpr�fen, und dann den Vergleich
im unsigned Bereich durchf�hren.

> Was ist der Grund f�r die Warnung?

Vermutlich dass manchen Leuten die C-Regeln bei so einem Vergleich
nicht immer ganz bewusst sind.
Bei

unsigned int a = 1;
int b = -1;
printf("a<b: %d\n", a < b);

wirst du 1 (also true) als Ergebnis bekommen,
bei
printf("a<b: %d\n", (long long)a < (long long)b);

dagegen 0 (also false).

Tom

Juergen Ilse

unread,
Nov 6, 2009, 4:21:51 AM11/6/09
to
Hallo,

iwl <Ingo...@gmx.de> wrote:
> wie bekommt man Warnungen für Vergleich signed/unsigned weg

Indem man auf solche verzichtet (oder, sofern man ganz sicher sein kann,
dass man im Wertebereich des "kleineren Datentypen" bleibt, durch ent-
sprechendes casten).

> Was ist der Grund für die Warnung?

Du vergleichst verschiedene Datentypen mit unterschiedlichem Wertebereich.
Das *kann* (muss aber nicht unbedingt) eine Fehlerquelle sein ...
Der Compiler darf vor allem und jedem warnen ohne den Standard zu verletzen
(z.B. auch vor der Verwendung des Zeichens "Q" in einer Zeichenkette) ...
Zugegebenermassen waere eine solche Warnung nur nervig und haette nicht die
geringsten Vorteile, deswegen wird das wohl eher kein Compilerbauer machen,
aber eine solche Warnung waere durchaus noch standardkonform ...

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...

Georg Bauhaus

unread,
Nov 6, 2009, 7:49:47 AM11/6/09
to
On 11/6/09 9:11 AM, Thomas Koller wrote:
> iwl<Ingo...@gmx.de> wrote:
>> wie bekommt man Warnungen f�r Vergleich signed/unsigned weg
>
> Meistens bekommt man die Warnung mit einem cast weg.

Oder anders gesagt, die Warnung verschwindet, wenn man ihren
Hinweis richtig deutet und das Programm nach M�glichkeit
korrigiert. Wie du ja weiter ausgef�hrt hast.

Rainer Weikusat

unread,
Nov 6, 2009, 7:57:13 AM11/6/09
to
iwl <Ingo...@gmx.de> writes:
> wie bekommt man Warnungen f�r Vergleich signed/unsigned weg und werden
> diese korrekt ausgef�hrt, sprich wenn signed negativ, dann ist es eben

> kleiner als die unsigned Variable.
> Was ist der Grund f�r die Warnung?

Der Grund fuer die Warnung ist, dass die gcc-Entwickler eine
kollektive Meise haben und als Menschen mit ueberwiegend
mathematischer Bildung vorzeichenlose Zahlen grundsaetzlich ablehnen,
egal ob die fuer irgendetwas praktisches, was nun wirklich nicht ihr
Metier ist, vielleicht nuetzlich sein sollten, vgl

* A comparison between signed and unsigned values could produce
an incorrect result when the signed value is converted to
unsigned.

Das folgende ist (meines Wissen nache) ein strikt konformes
C-Programm:

#include <stdio.h>

int main(void)
{
printf("%d\n", -1 < 1U);
return 0;
}

Und nach den relevanten Regeln der Sprache 'C' (nicht nach den
irrelvanten des staendigen Aenderungen unterworfenen Sprachenzoos
namens 'Mathematik') ist die korrekte Ausage 0 und nicht 1.

Rainer Weikusat

unread,
Nov 6, 2009, 8:10:33 AM11/6/09
to
Rainer Weikusat <rwei...@mssgmbh.com> writes:

[...]

> #include <stdio.h>
>
> int main(void)
> {
> printf("%d\n", -1 < 1U);
> return 0;
> }
>
> Und nach den relevanten Regeln der Sprache 'C' (nicht nach den
> irrelvanten des staendigen Aenderungen unterworfenen Sprachenzoos
> namens 'Mathematik') ist die korrekte Ausage 0 und nicht 1.

Hier sollte man noch anfuegen, dass obige Aussage strenggenommen
falsch ist und etwas in der Art von 'die relevanten mathematischen
Regeln gelten als vollkommen nutzloser, rein theoretischer Quatsch,
den man zwar vielleicht auswendig lernen muss, aber am besten
vollkommen ignoriert und/oder schnell wieder vergisst' der Wahrheit
vermutlich naeher kommit.

iwl

unread,
Nov 6, 2009, 7:48:25 PM11/6/09
to
Es ist nicht zu fassen, besonders, daß hier doch etliche der Meinung
sind, daß ich falsch liege -)

int t1=-1;
unsigned int t2=0xFFFFFFFF;
printf("%d", t1<t2);

und hier bekomme ich noch nicht mal ne Warnung.

Gibts irgendwo ein paar gute Webseiten wie man diesen Unsinn generell
behandelt, gibts da noch mehr von?

Rainer Weikusat

unread,
Nov 8, 2009, 1:25:27 PM11/8/09
to
iwl <Ingo...@gmx.de> writes:
> Es ist nicht zu fassen, besonders, da� hier doch etliche der Meinung
> sind, da� ich falsch liege -)

Du liegst falsch. Das ist keine Frage von 'Meinungen', sondern eine
der C-Sprachdefinition. Der relevante Abschnitt ist folgender:


Many operators that expect operands of arithmetic type cause
conversions and yield result types in a similar way. The
purpose is to determine a common real type for the operands
and result.

[...]

Otherwise, if the operand that has unsigned integer type has
rank greater or equal to the rank of the type of the other
operand, then the operand with signed integer type is
converted to the type of the operand with unsigned integer
type.
[6.3.1.8|1]

Die 'conversion ranks' von 'int' und 'unsigned' sind per Definition
gleich (6.3.1.1|1),


> int t1=-1;
> unsigned int t2=0xFFFFFFFF;
> printf("%d", t1<t2);

dh in diesem Fall ist der 'common real type' unsigned und (unsigned)-1
ist nach den in 6.3.1.3|2 definierten Konvertierungsregeln UINT_MAX.

Markus Wichmann

unread,
Nov 8, 2009, 1:21:40 PM11/8/09
to
iwl (Ingo...@gmx.de) schrieb:


Der Grund ist schnell genannt: Die Wertebereiche unterscheiden sich. Wie
bei allen Warnungen kann man diese ignorieren, wenn man ihre Ursache
entfernt hat. Und das kann man so hier (s ist jeweils signed, u nicht):

(s < u) -> (s < 0 || s < u)
(u < s) -> (s > 0 && u < s)

Der Standard schreib für Logik-Operatoren Shortcut Evaluation vor. Ist s
also in dem problematischen negativen Bereich, wird der problematische
Vergleich gar nicht erst ausgeführt. (Alternativ kann man natürlich auch
die Relation zwischen u und INT_MAX testen, aber mit der 0 find ich das
einfacher. Und man muss nicht die Konstante wechseln, wenn man den
Wertebereich wechsel (von int nach short etwa))

HTH,
Markus
--
Nur weil ein Genie nix reißt, muß ja nun nicht gleich jeder Idiot
pausieren... Bully hats ja auch geschafft.
-- gUnter nanonüm in de.alt.anime

Georg Bauhaus

unread,
Nov 8, 2009, 7:52:37 PM11/8/09
to
On 11/8/09 7:21 PM, Markus Wichmann wrote:
> Der Grund ist schnell genannt: Die Wertebereiche unterscheiden sich. Wie
> bei allen Warnungen kann man diese ignorieren, wenn man ihre Ursache
> entfernt hat. Und das kann man so hier (s ist jeweils signed, u nicht):
>
> (s< u) -> (s< 0 || s< u)
> (u< s) -> (s> 0&& u< s)


Ähm,

#include <stdio.h>

int main()
{
unsigned int u = 0;
signed int s = -1;

printf ("%d\n", u < s);
printf ("%d\n", s > 0 && u < s);
return 0;
}

Im zweiten Fall wird die Konvertierung von s in unsigned
beim u < s ausgeschaltet, sofern s < 0...

Claus Reibenstein

unread,
Nov 9, 2009, 3:07:53 AM11/9/09
to
Georg Bauhaus schrieb:

> On 11/8/09 7:21 PM, Markus Wichmann wrote:
>
>> Der Grund ist schnell genannt: Die Wertebereiche unterscheiden sich. Wie
>> bei allen Warnungen kann man diese ignorieren, wenn man ihre Ursache
>> entfernt hat. Und das kann man so hier (s ist jeweils signed, u nicht):
>>
>> (s< u) -> (s< 0 || s< u)
>> (u< s) -> (s> 0&& u< s)

Das sah im Original-Posting aber besser aus. Wer hat das so
verhässlicht? Du oder Dein Reader? Da Du Thunderbird benutzt, möchte ich
Letzteres eigentlich ausschließen ...

> int main()
> {
> unsigned int u = 0;
> signed int s = -1;
>
> printf ("%d\n", u < s);
> printf ("%d\n", s > 0 && u < s);
> return 0;
> }
>
> Im zweiten Fall wird die Konvertierung von s in unsigned
> beim u < s ausgeschaltet, sofern s < 0...

Dunkel ist Deiner Rede Sinn ...

Gruß. Claus

Georg Bauhaus

unread,
Nov 9, 2009, 4:21:05 AM11/9/09
to
On 11/9/09 9:07 AM, Claus Reibenstein wrote:
> Georg Bauhaus schrieb:
>
>> On 11/8/09 7:21 PM, Markus Wichmann wrote:
>>
>>> Der Grund ist schnell genannt: Die Wertebereiche unterscheiden sich. Wie
>>> bei allen Warnungen kann man diese ignorieren, wenn man ihre Ursache
>>> entfernt hat. Und das kann man so hier (s ist jeweils signed, u nicht):
>>>
>>> (s< u) -> (s< 0 || s< u)
>>> (u< s) -> (s> 0&& u< s)
>
> Das sah im Original-Posting aber besser aus. Wer hat das so
> verhässlicht? Du oder Dein Reader? Da Du Thunderbird benutzt, möchte ich
> Letzteres eigentlich ausschließen ...

Ist die Shredder-Version. (OK, öffentliche Tests haben manchmal
sichtbare Effekte, sorry.)

>> int main()
>> {
>> unsigned int u = 0;
>> signed int s = -1;
>>
>> printf ("%d\n", u< s);

>> printf ("%d\n", s> 0&& u< s);


>> return 0;
>> }
>>
>> Im zweiten Fall wird die Konvertierung von s in unsigned
>> beim u< s ausgeschaltet, sofern s< 0...
>
> Dunkel ist Deiner Rede Sinn ...

Dunkel wie die Tageszeit... Ich dachte mir noch, dass "ausgeschaltet"
kein so gutes Wort ist. -- Ist gemeint, dass (s > 0 && u < s) eine
geeignete Ersetzung für (u < s) ist? Die einzelnen Vergleiche arbeiten
mit folgenden Typen:

s > 0 ist (int) > (int)
u < s ist (unsigned) < (unsigned)

Rainer hat entsprechende Stellen aus dem Standard zitiert;
andeutungsweise steht das auch vorne in K&R.

Im Vergleich (u < s) allein werden unsigned-Werte verglichen.
s wird zu u und sein Wert sind die Bits von -1 als unsigned.
Das Ergebnis ist 1 für dann 0U < 0xffffffffU, zum Beispiel.
Das Ergebnis 1 ist für die Ersetzung (u < s) -> (s > 0 && u < s)
demnach zu überprüfen.
In (s > 0 && u < s) werden links von && ints verglichen.
Falls nicht s > 0 ist, findet der Vergleich u < s rechts von &&
nicht statt, das Ergebnis ist 0. u < s allein findet aber immer
statt und liefert hier das Ergebnis 1, nicht 0. Insofern
ist die Ersetzung nicht gültig.

Wenn ich ihre Absicht richtig verstanden habe.

Claus Reibenstein

unread,
Nov 9, 2009, 4:44:08 AM11/9/09
to
Georg Bauhaus schrieb:

> On 11/9/09 9:07 AM, Claus Reibenstein wrote:
>
>> Georg Bauhaus schrieb:
>>
>>> On 11/8/09 7:21 PM, Markus Wichmann wrote:
>>>
>>>> (s< u) -> (s< 0 || s< u)
>>>> (u< s) -> (s> 0&& u< s)
>>
>> Das sah im Original-Posting aber besser aus. Wer hat das so
>> verhässlicht? Du oder Dein Reader? Da Du Thunderbird benutzt, möchte ich
>> Letzteres eigentlich ausschließen ...
>
> Ist die Shredder-Version. (OK, öffentliche Tests haben manchmal
> sichtbare Effekte, sorry.)

Welche "Shredder-Version"? Ist das was Selbstgestricktes? ;-)

Ich hab's im Folgenden mal entshreddert.

>>> printf ("%d\n", s > 0 && u < s);
>>>

>>> Im zweiten Fall wird die Konvertierung von s in unsigned
>>> beim u < s ausgeschaltet, sofern s < 0...
>>
>> Dunkel ist Deiner Rede Sinn ...
>
> Dunkel wie die Tageszeit... Ich dachte mir noch, dass "ausgeschaltet"
> kein so gutes Wort ist.

:-)

> Im Vergleich (u < s) allein werden unsigned-Werte verglichen.

Richtig.

> In (s > 0 && u < s) werden links von && ints verglichen.
> Falls nicht s > 0 ist, findet der Vergleich u < s rechts von &&
> nicht statt,

Das ist das normale Verhalten bei logischen Operatoren: Sie werden von
links nach rechts ausgewertet, wobei nur die Teilausdrücke zur
Auswertung kommen, die für das Gesamtergebnis relevant sind.

> das Ergebnis ist 0.

... aber hier wird's schon wieder dunkel: Ein Vergleich, der nicht
stattfindet, hat auch kein Ergebnis.

Oder meintest Du das Gesamtergebnis?

Gruß. Claus

Georg Bauhaus

unread,
Nov 9, 2009, 5:04:27 AM11/9/09
to
On 11/9/09 10:44 AM, Claus Reibenstein wrote:

> Welche "Shredder-Version"? Ist das was Selbstgestricktes? ;-)

"Shredder" ist/war die Bezeichnung für Thunderbird 3 α-Versionen.

> Oder meintest Du das Gesamtergebnis?

Ja.

Rainer Weikusat

unread,
Nov 9, 2009, 7:16:55 AM11/9/09
to
Georg Bauhaus <rm-host...@maps.futureapps.de> writes:

[...]

> Dunkel wie die Tageszeit... Ich dachte mir noch, dass "ausgeschaltet"
> kein so gutes Wort ist. -- Ist gemeint, dass (s > 0 && u < s) eine

> geeignete Ersetzung f�r (u < s) ist? Die einzelnen Vergleiche arbeiten


> mit folgenden Typen:
>
> s > 0 ist (int) > (int)
> u < s ist (unsigned) < (unsigned)

[...]

> Im Vergleich (u < s) allein werden unsigned-Werte verglichen.
> s wird zu u und sein Wert sind die Bits von -1 als unsigned.

So stimmt das nicht ganz: Die entsprechende Formulierung lautet '[...]
the value is converted by repeatedly adding or subtracting one more
than the maximum value which can be represented in the new type until
the value is in the range of the new type'. Dazu gibt es dann noch
eine Fussnote, die erlaeutert, das diese Additionen oder Subtraktionen
'konzeptionell mathematisch' sein sollten, also nicht den
Beschraenkungen tatsaechlich existierender Ganzzahltypen unterworfen.

Konkret heisst das, dass (unsigned)-1 == UINT_MAX gilt, waehrend eine
binaere Representation von -1, angenommen int bestuende aus 31 Wertbits
und einem Vorzeichenbit, 'woertlich' auch 0x80000001
(sign-and-magntitude) oder 0xfffffffe (Einerkomplement) sein koennte.

[...]

>> unsigned int u = 0;
>> signed int s = -1;

[...]

> Das Ergebnis ist 1 f�r dann 0U < 0xffffffffU, zum Beispiel.
> Das Ergebnis 1 ist f�r die Ersetzung (u < s) -> (s > 0 && u < s)
> demnach zu �berpr�fen.


> In (s > 0 && u < s) werden links von && ints verglichen.
> Falls nicht s > 0 ist, findet der Vergleich u < s rechts von &&
> nicht statt, das Ergebnis ist 0. u < s allein findet aber immer
> statt und liefert hier das Ergebnis 1, nicht 0.

Das duerfte auch so beabsichtigt gewesen sein: Der Doppelvergleich hat
das Resultat, das jemand erwarten wuerde, fuer den unsigned
grundsaetzlich dasselbe wie int ist, lediglich 'komischerweise'
ausserstande, negative Zahlen darzustellen, aber dafuer mit doppelt so
grossem positiven Wertebereich. Das ist zwar falsch, denn unsigned
bezeichnet eine Untermenge der natuerlichen Zahlen und int eine
Teilmenge der ganzen Zahlen und fuer die Teilmengen von int und
unsigned, die nicht Bestandteil der entsprechenden Schnittmenge sind,
haben die relationalen Operatoren nicht die Bedeutung, die jemand
erwarten wuerde, dessen Gehirn sich irgendwann im Laufe des sechsten
oder siebten Schuljahres endgueltig abgeschaltet hat[*], koennte aber
vielleicht sogar nuetzlich sein.

[*] Es ist eigentlich erschreckend, dass Leute schon so frueh
nicht mehr durch Tatsachen zu erschuetternde Gewohnheiten
entwickeln ...

Markus Wichmann

unread,
Nov 10, 2009, 3:14:36 AM11/10/09
to
Georg Bauhaus (rm-host...@maps.futureapps.de) schrieb:

Witzbold. Wenn s < 0, schlägt im zweiten Fall der erste Test fehl. Somit
wird der zweite Test gar nicht erst ausgewertet, da beide Tests mit "&&"
verbunden sind.

Die erste printf-Zeile ist zwar definiertes Verhalten, aber sie könnte
etwas anderes tun, als der Leser erwartet. Es wird nämlich, falls s
außerhalb des Wertebereiches von unsigned liegt, solange UINT_MAX drauf
addiert, bis s wieder im Wertebereich von unsigned ist. Damit wird hier
nicht mehr zwischen 0 und -1, sondern zwischen 0 und UINT_MAX - 1
verglichen. Da liegen die Relationen dann doch ein bisschen auseinander.

Ups, lese gerade, dass nicht UINT_MAX, sondern UINT_MAX + 1 auf s
addiert wird. (6.3.1.3 p2)

Und ja, sicher tut (u < s) etwas anderes als (s > 0 && u < s). Mit
meinen Ersetzungen meinte ich: Wenn man das so schreibt, erhält man die
algebraischen Vergleichsoperatoren (d.h. -1 < 0), nicht die von C (wo
-1 > 0 gilt).

HTH,
Markus
P.S.: Hmm... kann es sein, dass die C-Standard-Schreiber hierbei an ein
Zweierkomplementsystem gedacht haben? Dort ist nämlich -1 eine endliche
Folge von Einsen, wenn man es binär darstellt. Und wenn man UINT_MAX + 1
draufaddiert, kommt genau das gleiche raus. D.h. Compiler auf
Zweierkomplementsystemen brauchen dieser Regel (6.3.1.3p2) keine
gesonderte Beachtung zu schenken, weil sie vom System direkt erfüllt
wird.

Markus Wichmann

unread,
Nov 10, 2009, 3:28:21 AM11/10/09
to
Rainer Weikusat (rwei...@mssgmbh.com) schrieb:

> Georg Bauhaus <rm-host...@maps.futureapps.de> writes:
>
> [...]
>
>> Dunkel wie die Tageszeit... Ich dachte mir noch, dass "ausgeschaltet"
>> kein so gutes Wort ist. -- Ist gemeint, dass (s > 0 && u < s) eine
>> geeignete Ersetzung für (u < s) ist? Die einzelnen Vergleiche arbeiten

>> mit folgenden Typen:
>>
>> s > 0 ist (int) > (int)
>> u < s ist (unsigned) < (unsigned)
>
> [...]
>
>> Im Vergleich (u < s) allein werden unsigned-Werte verglichen.
>> s wird zu u und sein Wert sind die Bits von -1 als unsigned.
>
> So stimmt das nicht ganz: Die entsprechende Formulierung lautet '[...]
> the value is converted by repeatedly adding or subtracting one more
> than the maximum value which can be represented in the new type until
> the value is in the range of the new type'. Dazu gibt es dann noch
> eine Fussnote, die erlaeutert, das diese Additionen oder Subtraktionen
> 'konzeptionell mathematisch' sein sollten, also nicht den
> Beschraenkungen tatsaechlich existierender Ganzzahltypen unterworfen.
>
> Konkret heisst das, dass (unsigned)-1 == UINT_MAX gilt, waehrend eine
> binaere Representation von -1, angenommen int bestuende aus 31 Wertbits
> und einem Vorzeichenbit, 'woertlich' auch 0x80000001
> (sign-and-magntitude) oder 0xfffffffe (Einerkomplement) sein koennte.
>
> [...]
>
>>> unsigned int u = 0;
>>> signed int s = -1;
>
> [...]
>
>> Das Ergebnis ist 1 für dann 0U < 0xffffffffU, zum Beispiel.
>> Das Ergebnis 1 ist für die Ersetzung (u < s) -> (s > 0 && u < s)
>> demnach zu überprüfen.

>> In (s > 0 && u < s) werden links von && ints verglichen.
>> Falls nicht s > 0 ist, findet der Vergleich u < s rechts von &&
>> nicht statt, das Ergebnis ist 0. u < s allein findet aber immer
>> statt und liefert hier das Ergebnis 1, nicht 0.
>
> Das duerfte auch so beabsichtigt gewesen sein: Der Doppelvergleich hat
> das Resultat, das jemand erwarten wuerde, fuer den unsigned
> grundsaetzlich dasselbe wie int ist, lediglich 'komischerweise'
> ausserstande, negative Zahlen darzustellen, aber dafuer mit doppelt so
> grossem positiven Wertebereich.

Korrekt, genau so habe ich das gemeint. Natürlich sind die Vergleiche
nicht äquivalent, denn wenn sie es wären, könnte man sich doch den
Doppelvergleich sparen, oder?

> Das ist zwar falsch, denn unsigned
> bezeichnet eine Untermenge der natuerlichen Zahlen und int eine
> Teilmenge der ganzen Zahlen

Was den Umstand, den du oben mit "komerscherweise" bezeichnet hast,
lediglich in mathematische Begriffe packt.

> und fuer die Teilmengen von int und
> unsigned, die nicht Bestandteil der entsprechenden Schnittmenge sind,
> haben die relationalen Operatoren nicht die Bedeutung, die jemand
> erwarten wuerde, dessen Gehirn sich irgendwann im Laufe des sechsten
> oder siebten Schuljahres endgueltig abgeschaltet hat[*], koennte aber
> vielleicht sogar nuetzlich sein.
>

Hilf mir auf die Sprünge: Was habe ich aus jener dunklen Epoche
vergessen? Ich studiere gerade Info, und die Mathematik, die ich
momentan betreibe, ist doch deutlich komplexer, als das, was wir in der
siebten Klasse gemacht haben. Wenn mir jetzt schon solche Grundlagen
fehlen, dürfte es schwierig werden, etwaige Prüfungen zu bestehen.

> [*] Es ist eigentlich erschreckend, dass Leute schon so frueh
> nicht mehr durch Tatsachen zu erschuetternde Gewohnheiten
> entwickeln ...


Falls du meinst, dass ich auf der Tatsache -1 < INT_MAX + 1 bestehe...

Übrigens hat dieser Thread dazu geführt, dass ich einen Bug in einem
Assemblerprogramm habe entfernen können. Die x86-Anweisung CMP macht
halt doch nur eine Subtraktion ohne Ergebnisspeicherung und ohne
Intelligenz.

Jetzt teste ich einfach vorher das Vorzeichenbit des signed-Operanden
ab, und nur wenn das nicht gesetzt ist, kommt der Code überhaupt bis zum
CMP :-)

Tschö,

Georg Bauhaus

unread,
Nov 10, 2009, 6:03:45 AM11/10/09
to
Markus Wichmann schrieb:

> Georg Bauhaus (rm-host...@maps.futureapps.de) schrieb:
>> On 11/8/09 7:21 PM, Markus Wichmann wrote:
>>> Der Grund ist schnell genannt: Die Wertebereiche unterscheiden sich. Wie
>>> bei allen Warnungen kann man diese ignorieren, wenn man ihre Ursache
>>> entfernt hat. Und das kann man so hier (s ist jeweils signed, u nicht):
>>>
>>> (s< u) -> (s< 0 || s< u)
>>> (u< s) -> (s> 0&& u< s)

> Und ja, sicher tut (u < s) etwas anderes als (s > 0 && u < s). Mit


> meinen Ersetzungen meinte ich: Wenn man das so schreibt, erhält man die
> algebraischen Vergleichsoperatoren (d.h. -1 < 0), nicht die von C (wo
> -1 > 0 gilt).

OK. Das von Rainer zurecht angesprochene Problem scheint mir,
dass ein mathematisch eben nicht korrektes Naiv-Verständnis von Cs
"Ganzzahl"-Operationen Unheil anrichtet, und dass Tesafilm-Ersetzungen
(wenn ich sie mal so umschreiben darf)
keine allgemeine Lösung darstellen, obwohl letztere menschenmöglich
und bestimmt hilfreich wäre: Statt in den Köpfen
von Programmierern die passende mathematische Struktur für unsigned
in Erinnerung zu rufen, bzw. die passende Menge von Strukturen
für int, und diese dann zu verbinden, wird das Problem zu halbieren
versucht. Damit irgendwie auf Biegen und Brechen noch an die
"bekannte" Schulmathematik anschließen werden kann, scheint mir.
Gerade in mathematischen Köpfen sollten geeignete algebraische
Strukturen doch keine Lernprobleme bereiten?

Eine interessante Aufgabe wäre (aus meine naiven Sicht jedenfalls),
die ausschlaggebenden Algebren von Cs Typen gut darzustellen.
Die Darstellung wäre ideal, wenn Programmier-Anfänger in C
von Anfang an lernen könnten, dass (int, +,-,*,..., <, ...) eben
nicht den Gesetzen von (Z, +,-,*,..., <, ...) folgt!
Es geht bei C ganz überwiegend um Digitalcomputer und deren
Register, weniger um die Menge Z. Das zu beachten hat Vorteile.

Cs Operationen ohne diese Strukturen zu erklären, ist nicht nur eine
versäumte Gelegenheit, konkrete Anwendungsfälle für abstrakte mathematische
Strukturen zu demonstrieren. Die fehlende Erklärung ist auch ein
folgenreicher Fehler, der uns allwöchentlich int-overflow-CVEs schenkt.
Was man als genug Beleg für die Dringlichkeit der Maßnahme sehen kann.

0 new messages