Implementierung des sizeof-Operators

Lesezeit: 4 Minuten

Benutzer-Avatar
Raghu Srikanth Reddy

Ich habe versucht, den sizeof-Operator zu implementieren. Ich habe es so gemacht:

#define my_sizeof(x) ((&x + 1) - &x)

Aber es endete immer damit, dass das Ergebnis ‘1’ für einen der Datentypen war.

Ich habe dann gegoogelt und folgenden Code gefunden:

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

Und der Code funktioniert, wenn er es ist typisiert, ich verstehe nicht warum. Dieser Code polstert auch eine STRUKTUR perfekt auf.

Es funktioniert auch für:

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x)

Kann mir bitte jemand erklären, wie es funktioniert, wenn es typisiert ist?

  • Casting zu unsigned int ist eine schlechte Idee. uintptr_t ist besser, beinhaltet aber immer noch eine lästige, aber unvermeidbare implizite Konvertierung.

    – Pascal Cuoq

    5. Januar 2013 um 11:12 Uhr


  • Sie im Grunde kann nicht implementieren sizeof. Es ist ein wesentlicher Bestandteil der C-Sprache

    – Basile Starynkevitch

    2. April 2019 um 7:24 Uhr

Das Ergebnis der Zeigersubtraktion ist in Elemente und nicht in Byte. Somit wird der erste Ausdruck zu ausgewertet 1 per Definition.

Abgesehen davon sollten Sie in Makros wirklich Klammern verwenden:

#define my_sizeof(x) ((&x + 1) - &x)
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

Ansonsten versuchen zu verwenden my_sizeof() in einem Ausdruck kann zu Fehlern führen.

  • Die Makros sind als Ersatz hoffnungslos sizeof. Sie bewerten das Argument (auch zweimal) … Denken Sie an my_sizeof(x++).

    – Matte

    5. Januar 2013 um 11:09 Uhr

Benutzer-Avatar
Basile Starynkevitch

Das sizeof -Operator ist Teil der C- (und C++)-Sprachspezifikation und wird im Compiler (dem Front-End) implementiert. Es gibt keine Möglichkeit, es mit anderen C-Konstrukten zu implementieren (es sei denn, Sie verwenden GCC-Erweiterungen wie Art der), weil es entweder Typen oder Ausdrücke als Operanden akzeptieren kann, ohne Nebeneffekte (z sizeof((i>1)?i:(1/i)) wird nicht abstürzen, wenn i==0 aber dein Makro my_sizeof würde bei einer Division durch Null abstürzen). Siehe auch C-Codierungsrichtlinienund Wikipedia.

Du solltest C verstehen Zeigerarithmetik. Siehe zB diese Frage. Die Zeigerdifferenz wird in Elementen und nicht in Bytes ausgedrückt.

Benutzer-Avatar
Kuppappa DH

#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x)

Dies my_sizeof() Makro funktioniert in den folgenden Fällen nicht:

  1. sizeof 1 – 4 Byte (für eine Plattform mit 4-Byte int)
    my_sizeof(1) – überhaupt nicht kompilieren.

  2. sizeof (int) – 4 Byte (für eine Plattform mit 4-Byte int)
    my_sizeof(int) – Kompiliert überhaupt keinen Code.

Es funktioniert nur für Variablen. Es funktioniert nicht für Datentypen wie int, float, char etc., für Literale wie 2, 3.4, 'A'etc., noch für rvalue-Ausdrücke wie a+b oder foo().

  • Dies wäre ein großartiger Kommentar, weil es die gestellte Frage nicht beantwortet, aber es ist “konstruktive Kritik, die den Autor bei der Verbesserung des Beitrags anleitet” …

    – autistisch

    3. Februar 2016 um 18:24 Uhr

  • Aufgrund der Ausrichtung wird die Größe auch überhaupt nicht korrekt gemeldet. Beispielsweise gibt eine 6 Byte große Variable 8 aus.

    – Ol Sen

    6. Januar 2021 um 16:04 Uhr


  • @OlSen Wenn &x + 1 ist 8 Byte nach &xdann das sizeof(x) ist eigentlich 8: “Bei der Zeigersubtraktion wird das Ergebnis der Differenz zwischen den Zeichenzeigern auf ähnliche Weise dividiert durch die Größe des Objekts, auf das ursprünglich gezeigt wurde.”

    – Andreas Henle

    12. Februar um 11:59 Uhr


#define my_sizeof(x) ((&x + 1) - &x)

&x liefert die Adresse der im Programm deklarierten Variablen (sagen wir Double x) und inkrementiert mit 1 ergibt die Adresse, wo die nächste Variable vom Typ x gespeichert werden kann (hier addr_of(x) + 8denn die Größe eines Doubles beträgt 8Byte).

Die Differenz ergibt das Ergebnis, wie viele Variablen vom Typ von x kann in der Speichermenge gespeichert werden, die für den Typ x offensichtlich 1 ist (um ihn um 1 zu inkrementieren und die Differenz zu bilden, haben wir getan).

#define my_size(x) ((char *)(&x + 1) - (char *)&x)

typisieren es in char* und die Differenz wird uns sagen, wie viele Variablen des Typs char können im angegebenen Speicherplatz gespeichert werden (die Differenz). Seit jeder char benötigt nur 1 Byte Speicher daher (Menge an Speicher)/1 gibt die Anzahl der Bytes zwischen zwei aufeinanderfolgenden Speicherstellen des Variablentyps an, der an das Makro übergeben wird, und somit die Speichermenge, die die Variable des Typs hat x erfordert.

Sie können diesem Makro jedoch kein Literal übergeben und dessen Größe kennen.

Aber es endete immer damit, dass das Ergebnis ‘1’ für einen der Datentypen war

Ja, so funktioniert Zeigerarithmetik. Es funktioniert in Einheiten des Typs, auf den gezeigt wird. Also Casting zu char * Werkseinheiten von charwas du willst.

Benutzer-Avatar
SakthiKarthik

Dies funktioniert sowohl für Literale als auch für Variablen.

#define my_sizeof(x) (char*) (&(((__typeof__(x) *)0)[1])) - (char *)(&(((__typeof__(x) *)0)[0]))

Benutzer-Avatar
CY

Ich habe gestern gesucht und dieses Makro gefunden:

#define mysizeof(X)  ((X*)0+1)

Was X nur einmal erweitert (kein Fehler als doppelte Auswertung von Ausdrücken wie x++), und es funktioniert bis jetzt gut.

  • Obwohl dieses Makro bei meinen Tests mit Strukturen keinen Fehler hatte, deckt die Verwendung des Operators viel allgemeinere Situationen ab. Beispielsweise kann mysizeof(2) nicht kompiliert werden, aber sizeof(2) ergibt 4, die Größe der Ganzzahl.

    – CY

    26. Juni 2018 um 14:48 Uhr


  • Erwarteter Ausdruck.

    – Ol Sen

    6. Januar 2021 um 16:50 Uhr

1365440cookie-checkImplementierung des sizeof-Operators

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy