uint32_t zu int16_t?

OP #4821895
Guten Abend,

ich hab eine allgemeine Funktion geschrieben, die einen uint32_t-Wert 
zurück gibt. Es kann jedoch auch vorkommen, dass es sich um eine 
negative (also einen signed Wert) Zahl handelt. Meine Frage ist nun, ob 
das ganze einfach durch einen expliziten Typecast gelöst werden kann? 
Z.B. so:
1
uint32_t result = myFunc();
2
int16_t signedValue = (int16_t)result;
Das Verhalten vorzeichenbehafteter Typen bei Überlauf ist offiziell 
undefiniert. Du wirst sehr wahrscheinlich einfach bloss die unteren 16 
Bits kriegen, mit und ohne Cast.

Der Cast wird dir ggf. eine aggressiv eingestellte Warnung ersparen, 
aber typischerweise nichts am erhaltenen Wert ändern. Eine Sättigung zu 
grosser oder kleiner Werte auf die Limits erfolgt nicht.
OP
Mark B. schrieb:
> Max M. schrieb:
>> Guten Abend,
>>
>> ich hab eine allgemeine Funktion geschrieben, die einen uint32_t-Wert
>> zurück gibt. Es kann jedoch auch vorkommen, dass es sich um eine
>> negative (also einen signed Wert) Zahl handelt.
>
> Dann muss die Funktion eben einen vorzeichenbehafteten Wert zurückgeben.

Das wird etwas schwierig, da die Funktion auch teilweise für 
unsigned-Werte benutzt wird. Schade, ich dachte ich könnte das alles mit 
einer Funktion abbilden.
Max M. schrieb:
>> Dann muss die Funktion eben einen vorzeichenbehafteten Wert zurückgeben.
>
> Das wird etwas schwierig, da die Funktion auch teilweise für
> unsigned-Werte benutzt wird.

Das klingt wenig sinnvoll. Und woran erkennt der Aufrufer eigentlich, ob 
der Wert vorzeichenbehaftet sein soll oder nicht?
Max M. schrieb:
> Das wird etwas schwierig, da die Funktion auch teilweise für
> unsigned-Werte benutzt wird.

Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es 
nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte 
Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei 
signed zu bleiben.
OP
Rolf M. schrieb:
> Das klingt wenig sinnvoll. Und woran erkennt der Aufrufer eigentlich, ob
> der Wert vorzeichenbehaftet sein soll oder nicht?

Gar nicht, der Aufrufer bin nur ich. Ich lese Werte aus verschiedenen 
Registern, laut Datenblatt ist ein Wert als short zu interpretieren, die 
restlichen jedoch als unsigned short.
Das scheint broken-by-design.

Du hast einen Algorithmus und kombinierst signed und unsigned. Alles 
klar.

Du hast einen anderen(!) Algorithmus, bei dem unsigned uns unsigend 
kombiniert wird. Alles klar.

Also entweder überladen falls unterschiedliche Signatur oder template.
Max M. schrieb:
> Rolf M. schrieb:
>> Das klingt wenig sinnvoll. Und woran erkennt der Aufrufer eigentlich, ob
>> der Wert vorzeichenbehaftet sein soll oder nicht?
>
> Gar nicht, der Aufrufer bin nur ich. Ich lese Werte aus verschiedenen
> Registern, laut Datenblatt ist ein Wert als short zu interpretieren, die
> restlichen jedoch als unsigned short.

Man muss ja nicht zwingend eine einzige Funktion schreiben, die alle 
Fälle abdeckt. Man darf dies sogar mit zwei oder mehr Funktionen 
erledigen :-)
Vllt könnte der TO mal sagen, ob es denn nun C oder C++ sein soll. Dann 
könnte man weiter kommen mit den Vorschlägen:

- unterschiedliche Funktionen/Namen (C)

- überladen, falls unterschiedliche Signatur möglich(C++)

- template spezialisierungen, falls identische Signatur (C++)

- ...
Gast
Sebastian V. schrieb:
> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
> signed zu bleiben.

Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau 
andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher 
bin signed zu brauchen nutz ich das auch.
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Sehe ich auch so.
Gast
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Z.B. ist ein Überlauf von signed-Variablen "undefined behavior". Der 
Compiler darf also annehmen, dass das nicht auftritt. Was wesentlich 
mehr Gelegenheiten zum Optimieren zur Folge hat.
ui schrieb:
> Sebastian V. schrieb:
>> Und aus welchen Gründen brauchst du unbedingt unsigned? Wenn man es
>> nicht gerade mit Bitgeshifte zu tun hat oder man auf das definierte
>> Überlaufverhalten von unsigned angewiesen ist, sollte man versuchen bei
>> signed zu bleiben.
>
> Die Aussage interessiert mich jetzt. Weil ich behaupte, dass es genau
> andersrum ist. Ich nutze immer unsigned, nur wenn ich wirklich sicher
> bin signed zu brauchen nutz ich das auch.

Das kann zu unerwarteten Problemen bei Berechnungen und Vergleichen 
führen, wenn man dann doch einen Signed-Wert braucht und den dann mit 
einem Unsigned vergleicht. So was typisches ist z.B. eine Größenangabe. 
Klar, die Maximalgröße ist doppelt so groß, wenn man unsigned nimmt. 
Braucht man aber einen Offset zwischen zwei Elementen, kann dieser auch 
negativ sein, und es ist nicht mehr in jedem Fall möglich, einen Offset 
zwischen zwei beliebigen Elementen anzugeben - zumindest nicht ohne 
einen Wrap-Around.
Man kriegt bei Vergleichen oder Berechnungen mit gemischt signed und 
unsigned auch eine Warnung vom GCC deswegen.
Das hat sogar dazu geführt, dass Sprachen wie z.B. Java unsigned-Typen 
nicht mal kennen (was ich aber auch für Blödsinn halte).
Gast
Rolf M. schrieb:
> Das kann zu unerwarteten Problemen bei Berechnungen und Vergleichen
> führen, wenn man dann doch einen Signed-Wert braucht und den dann mit
> einem Unsigned vergleicht.

Das stimmt. Allerdings gilt auch das:
tictactoe schrieb:
> Z.B. ist ein Überlauf von signed-Variablen "undefined behavior".

Damit ist aber "offiziell" kein free-running-counter (a la Systicker) 
mehr möglich.

Zudem ist jede Division durch 2^n eine echte Division (statt shift), da 
die Zahl ja negativ sein könnte.

Bitte versteh mich nicht falsch, ich finde diese 
signed/unsigned-Probleme als mit die schlimmsten bei C. Wie man sich 
auch entscheidet, es holt einen ein.
Max M. schrieb:
> Gar nicht, der Aufrufer bin nur ich. Ich lese Werte aus verschiedenen
> Registern, laut Datenblatt ist ein Wert als short zu interpretieren, die
> restlichen jedoch als unsigned short.

Warum gibst du dann keinen signed Typen zurück, der größer als unsigned 
short ist? Also long?


Das Problem gibt es doch schon bei der Standardfunktion getc.
Die liefert Zeichen als positive int-Werte zurück, obwohl char selber 
häufig signed ist.
Spielt bei ASCII keine Rolle, aber bei den allermeisten Erweiterungen 
gibt es Probleme.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.