Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

niratschi

Frischling

  • »niratschi« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

1

19.04.2012, 14:32

sizeof(), if and preprozessor

Hi,
Ich versuche gerade herauszufinden, wie sizeof im Präprozessor interpretiert wird. Erstmal ein Codebeispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
int main()
{
    int a=12;
    int b=0;
    if(b - sizeof(a) >= 0) printf("True\n”");
    else printf("False\n");
        
}


Da if im Präprozessor, sizeof aber erst im Compiler bearbeitet wird, ist die Ausgabe hier "True". Mich würde aber interessieren, wie der Präprozessor hierbei sizeof auffasst. Online habe ich mehrmals gelesen, sizeof() würde als 0 ersetzt werden, aber demnach sollte folgender Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main()
{
    int a=12;
    int b=0;
    if(sizeof(a) == 0) printf("True\n”");
    else printf("False\n");
        
}


auch "True" ergeben. allerdings ist hier die Ausgabe "False". Als 0 kann sizeof also nicht interpretiert werden. Zuletzt funktioniert das ganze wenn man sizeof mit (int) castet:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main()
{
    int a=12;
    int b=0;
    if(b - (int)sizeof(a) >= 0) printf("True\n”");
    else printf("False\n");
        
}


Dies ergibt "False", wird richtig errechnet.
Meine Fragen:

1. Wie behandelt der Präprozessor sizeof()? / Kann mir jemand die obigen Ergebnisse erklären?
2. Warum wird durch casten von sizeof die Rechnung richtig?

mfg, niratschi
++++++[>+++++++++++>+++++++<<-]>+.>+..

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

19.04.2012, 14:51

"if" wird nicht im Präprozessor ausgewertet, "#IF" wird. Damit macht dann plötzlich alles da einen Sinn.
b ist 0.
sizeof(a) ist das selbe wie (int)sizeof(a) und in jedem Fall zur Laufzeit größer 0.
Somit ist "b - (int)sizeof(a)" dasselbe wie "b - sizeof(a)" und immer kleiner als 0, weil 0-x < 0, falls x > 0. Daher auch "False". Alles weitere ist bedingt durch Überläufe Deiner Operationstypen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (19.04.2012, 14:56)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

3

19.04.2012, 14:55

Zitat

Ich versuche gerade herauszufinden, wie sizeof im Präprozessor interpretiert wird.

"sizeof" hat NICHTS mit dem Präprozessor zu tun!

Zitat

Da if im Präprozessor, sizeof aber erst im Compiler bearbeitet wird, ist die Ausgabe hier "True".

Kann eigentlich nicht sein.
Wahrscheinlich findet ein Überlauf(Unterlauf) statt.
"If" wird übrigens ebenfalls nicht im Präprozessor bearbeitet.

Zitat

Online habe ich mehrmals gelesen, sizeof() würde als 0 ersetzt werden

Ich weiß nicht wo du das gelesen hast, aber das ist FALSCH.
"sizeof" wird mit dem Speicherplatzbedarf (in Bytes) des Typen ersetzt. "sizeof(int)" liefert in 32Bit-Code daher immer 4.

Zitat

Warum wird durch casten von sizeof die Rechnung richtig?

"sizeof" liefert einen vorzeichenlosen Typen "size_t" zurück.
Erst wenn dieser explizit umgewandelt wird, wird der Überlauf(Unterlauf) verhindert.

Folgende Rechnung müsste somit wahr sein:

C-/C++-Quelltext

1
0 - (size_t)4 == 4294967292


EDIT: Ich sehe gerade, da war jemand schneller. :D

niratschi

Frischling

  • »niratschi« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

4

19.04.2012, 15:18

"if" wird nicht im Präprozessor ausgewertet, "#IF" wird. Damit macht dann plötzlich alles da einen Sinn.
b ist 0.
sizeof(a) ist das selbe wie (int)sizeof(a) und in jedem Fall zur Laufzeit größer 0.
Somit ist "b - (int)sizeof(a)" dasselbe wie "b - sizeof(a)" und immer kleiner als 0, weil 0-x < 0, falls x > 0. Daher auch "False". Alles weitere ist bedingt durch Überläufe Deiner Operationstypen.
Okay, stimmt, #IF wird da ausgewertet. Trotzdem ist die Ausgabe von b-sizeof(a) eben nicht False wie du vermutest, sondern True. Das ganze geht ursprünglicherweise von einer Aufgabe an der Uni aus, wo wir eben genau dies untersuchen sollen. Ebenfalls wenn ich einfach nur

C-/C++-Quelltext

1
2
if(- sizeof(a) >= 0) ausgabe1;
else ausgabe2;


nehme, wird dies auch nicht ausgeführt, wie man erwarten sollte, es kommt auch ausgabe1 raus. Dies ändert sich allerdings durch das casten, nun kommt False raus. Es scheint also trotzdem sizeof() nicht komplikationsfrei mit if zu laufen.

Edit:

Zitat

"sizeof" liefert einen vorzeichenlosen Typen "size_t" zurück.

Erst wenn dieser explizit umgewandelt wird, wird der Überlauf(Unterlauf) verhindert.
Dies erklärt mir das ganze, danke. Ich war da mit dem Präprozessor völlig auf dem Holzweg^^. Danke!
++++++[>+++++++++++>+++++++<<-]>+.>+..

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

19.04.2012, 15:35

Dies ändert sich allerdings durch das casten, nun kommt False raus. Es scheint also trotzdem sizeof() nicht komplikationsfrei mit if zu laufen

Siehe mein letzter Satz.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

niratschi

Frischling

  • »niratschi« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

6

19.04.2012, 15:42

Dann noch eine Frage:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
struct data_t {
    int id;
    int x, y;
    };
void copy_data(struct data_t *val, int maxbyte)
{
        printf("maxbyte: %d\n*val: %d\n" ,maxbyte, sizeof(*val));
        printf("maxbyte-*val: %d\n", maxbyte-sizeof(*val));
    if(maxbyte - sizeof(*val) >= 0){
            printf("True\n");
        }
        else{
            printf("False\n");
        }
}

int main()
{
    struct data_t test={3,4,5};
    copy_data(&test, 0);
}


Die Ausgabe ist folgende:
maxbyte: 0
*val: 12
maxbyte-*val: -12
True

Die Berechnung von

C-/C++-Quelltext

1
printf("maxbyte-*val: %d\n", maxbyte-sizeof(*val));

ergibt also -12, die (selbe) Berechnung bei if:

C-/C++-Quelltext

1
if(maxbyte - sizeof(*val) >= 0)

ergibt allerdings eine Zahl >= 0. Letzteres ist ja nach der Erklärung von size_t zu verstehen, aber warum errechnet er dann oben den richtigen Wert? Wird das Ergebnis durch %d schon gecastet?

vielen Dank für die Hilfe,
niratschi
++++++[>+++++++++++>+++++++<<-]>+.>+..

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

19.04.2012, 16:02

%d stellt einen Wert als vorzeichenbehaftet in Text-Form dar. Die Zahl 0xFFFFFFFF ist positiv oder negativ, je nachdem wie man sie interpretiert. %d interpretiert sie als negativ, weil %d davon ausgeht, dass die Zahl mit Vorzeichen behandelt werden soll. %u (?) würde das nicht tun.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

niratschi

Frischling

  • »niratschi« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Hessen

Beruf: Student

  • Private Nachricht senden

8

19.04.2012, 17:38

Danke, jetzt ist es klar. Danke euch beiden, dass ihr mich von diesem Irrweg weggeleitet habt^^

mfg, niratschi
++++++[>+++++++++++>+++++++<<-]>+.>+..

Werbeanzeige