Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: C (alle ISO-Standards) ::  Ist dieses Codefragment "Endian-Safe"?  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Thez
Mitglied

Benutzerprofil
Anmeldungsdatum: 30.06.2014
Beiträge: 23
Beitrag Thez Mitglied 10:02:11 12.01.2017   Titel:   Ist dieses Codefragment "Endian-Safe"?            Zitieren

Guten Tag,

ich hab eine itoa Funktion geschrieben für eine Art Hausaufgabe:
C:
1
2
3
4
5
6
7
8
9
10
static uint32_t itoa_dot(uint8_t input){
    uint8_t output[4];
    output[3] = '.';
    int digits = 3;
    while(digits--){
        output[digits] = (input%10)|'0'; /* konvertierung zu ASCII */
        input /= 10;
    }
    return *((uint32_t*)output);
}

Wenn ich also 255 als input nehme, kommt ein {'2','5','5','.'} Array raus, dass dann gecastet wird.

Für mein Little Endian System klappt es, und nach meiner Logik eigentlich auch für Big-Endiansysteme.
Mich wundert es eher, dass der cast beim return nichts an der Bytereihenfolge ändert.
Ist das so Portable?

Mit freundlichen Grüßen,
Thez


Zuletzt bearbeitet von Thez am 10:03:04 12.01.2017, insgesamt 1-mal bearbeitet
DirkB
Mitglied

Benutzerprofil
Anmeldungsdatum: 24.01.2016
Beiträge: 727
Beitrag DirkB Mitglied 10:42:01 12.01.2017   Titel:              Zitieren

Wie greifst du auf die Daten wieder zu?

Mit einem + '0' wäre es noch portabler.


Warum der Mist?
Thez
Mitglied

Benutzerprofil
Anmeldungsdatum: 30.06.2014
Beiträge: 23
Beitrag Thez Mitglied 10:56:14 12.01.2017   Titel:              Zitieren

Ich konvertiere eine Networkbyteorder in_addr_t in das dottet-Format. Ich soll explizit keine Funktionen irgendeiner Library benutzen.
Also fallen auch printf-Varianten weg.

Die Funktion, die diese hier aufruft, verwaltet ein int32_t[4] Objekt, in welches ich je nach System die Rückgaben der itoa_dot Funktion einordne.

Am Ende füg ich das '\0' Byte hinzu, geb nen char* auf das Objekt zurück und alles ist gut.
scrontch
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.08.2000
Beiträge: 1651
Beitrag scrontch Mitglied 11:04:35 12.01.2017   Titel:              Zitieren

C-style casts ändern soviel ich weiss nie was am Speicherlayout.
Das ist einfach eine andere Reinterpretaion dessen was da an der Adresse steht.
So wie es aussieht missbrauchst Du uint32_t hier einfach als Zwischenspeicher für ein 4-Byte-Array?
Ich bin mr nicht ganz sicher ob der Standard vorschreibt dass das Speicherlayout eines uint32_t äquivalent zu 4 aufeinanderfolgenden uint8_t sein muss.
(das wäre eine grössere Garantie als nur zu garantieren dass uint32_t genau 32 und uint8_t genau 8 bit gross sind.)
Falls diese Garantie aber gilt sollte Endianess keine Probleme bereiten, da Du ja genau bestimmst was wo hinkommt.
Thez
Mitglied

Benutzerprofil
Anmeldungsdatum: 30.06.2014
Beiträge: 23
Beitrag Thez Mitglied 11:11:05 12.01.2017   Titel:              Zitieren

Ja genau, ich hab ein int32_t Array (also in der aufrufenden Funktion), das gefüllt werden muss. Und ich missbrauche wie beschrieben :D Bei Arrays habe ich ja Kontrolle darüber wie das Speicherlayout aussieht.
Ich hatte mir sorgen gemacht, dass der Cast das ganze zerstört, weil int-objekte eben von Endianess "befallen" sind. Aber wenn Casts daran nichts ändern bin ich guter Dinge.


Zuletzt bearbeitet von Thez am 11:12:33 12.01.2017, insgesamt 1-mal bearbeitet
DirkB
Mitglied

Benutzerprofil
Anmeldungsdatum: 24.01.2016
Beiträge: 727
Beitrag DirkB Mitglied 11:46:34 12.01.2017   Titel:              Zitieren

Es wäre sinnvoller, du übergibst einfach die Anfangsadresse von einem char-Buffer.

Portabel ohne Nachdenken.
Wutz
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.04.2010
Beiträge: 3818
Beitrag Wutz Mitglied 11:17:50 13.01.2017   Titel:              Zitieren

Thez schrieb:

Am Ende füg ich das '\0' Byte hinzu, geb nen char* auf das Objekt zurück und alles ist gut.

Naivling.
Du gibst vor, dir um Portabilität Gedanken zu machen und produzierst durch diesen beschriebenen Anfängerschrott schon mal selbst UB (Zugriff auf undefinierten Speicher nach deinem "Array").
Dein Rumgecaste ist ebenso UB (wegen type punning pointer dereference).
Der Missbrauch von uint32_t als char[4] ist schlimmstes Pfuscher-JW Niveau.

_________________
Java, the best argument for Smalltalk since C++. -- Frank Winkler
scrontch
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.08.2000
Beiträge: 1651
Beitrag scrontch Mitglied 11:45:43 13.01.2017   Titel:              Zitieren

Wutz schrieb:
...


Nun beruhig dich mal wieder. Kein Grund beleidigend zu werden.
Er hat von Anfang an von Hausaufgabe geredet. Da stell ich keine Anforderungen wie and Production Code.
Dein erster Einwand ist unberechtigt wenn er den letzten Punkt mit '\0' *ersetzt* (das interpretier ich mal so), dann belibt er noch innerhalb seiner Grnezen:
Er hat dann '2','5','5','.','2','5','5','.','2','5','5','.','2','5','5','\0' = 16 Bytes im Speicher von einem int32_t[4] liegen. Das passt gerade.
Bzgl type punning cast geht es ja gerade hauptsächlich in der Frage. Was ist hier genau UB?
Wutz
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.04.2010
Beiträge: 3818
Beitrag Wutz Mitglied 12:16:21 13.01.2017   Titel:              Zitieren

Dein Beitrag ist sinnfrei.
Wenn du keine Ahnung hast, unterlasse einfach deine Beiträge hier.
Sie tragen nichts zum Thema bei und stiften nur Verwirrung.

_________________
Java, the best argument for Smalltalk since C++. -- Frank Winkler
Thez
Mitglied

Benutzerprofil
Anmeldungsdatum: 30.06.2014
Beiträge: 23
Beitrag Thez Mitglied 12:27:39 13.01.2017   Titel:              Zitieren

Da habe ich mich ja schnell unbeliebt gemacht. Aber gegen Anfänger sag ich auch garnichts.

Das '\0' Byte ersetzt einen der Punkte, also noch in dem Stackobjekt.
Ich geb zu, dass das Ganze nicht annährend elegant ist.

Aber ich merke schon, portability scheint ein großes Wort zu sein dass ich lieber nicht einfach so in den Mund nehme.

Dann beschränke ich mich darauf: Kann ich davon aus gehen, dass der cast Grundsätzlich nichts am Speicherlayout verändert?

Edit: Ist es mit Unions vllt. besser?


Zuletzt bearbeitet von Thez am 14:56:23 13.01.2017, insgesamt 2-mal bearbeitet
C++ Forum :: C (alle ISO-Standards) ::  Ist dieses Codefragment "Endian-Safe"?  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.