Kann das der Preprozessor?

Hallo, wird bei folgenden defines

#define SIZE_A 13
#define SIZE_B 8
#define SIZE_C 2
#define SIZE_D 10

#define INDEX_A 0
#define INDEX_B INDEX_A + SIZE_A
#define INDEX_C INDEX_B + SIZE_B
#define INDEX_D INDEX_C + SIZE_C
#define INDEX_E INDEX_D + SIZE_D

den Werten Index_B bis Index_E der korrekte Wert (13,21,23,33) zugewiesen?

Gruß Robert

Ja,

warum nicht?

Hast Du es mal ausprobiert?

Gruß, Lutz

PS: Kann natürlich auch eine Fangfrage sein, die Konstanten müssen nur ausgewertet werden, wenn sie gebraucht werden, und die Makros sind keine Variablen. Bzw. werden nur vom Präprozessor als solche verwendet. Ansonsten wird ihr Wert direkt im Progamm eingesetzt, da findet keine Zuweisung statt.

Hallo,

Hallo, wird bei folgenden defines

#define SIZE_A 13
#define SIZE_B 8
#define SIZE_C 2
#define SIZE_D 10

#define INDEX_A 0
#define INDEX_B INDEX_A + SIZE_A
#define INDEX_C INDEX_B + SIZE_B
#define INDEX_D INDEX_C + SIZE_C
#define INDEX_E INDEX_D + SIZE_D

den Werten Index_B bis Index_E der korrekte Wert (13,21,23,33)
zugewiesen?

Nein. Die Zuweisung ist
INDEX_A = 0 + 13
INDEX_B = 0 + 13 + 8
INDEX_C = 0 + 13 + 8 + 2
INDEX_D = 0 + 13 + 8 + 2 + 10

Damit:

$ gcc -E -
#define SIZE\_A 13
#define SIZE\_B 8
#define SIZE\_C 2
#define SIZE\_D 10

#define INDEX\_A 0
#define INDEX\_B INDEX\_A + SIZE\_A
#define INDEX\_C INDEX\_B + SIZE\_B
#define INDEX\_D INDEX\_C + SIZE\_C
#define INDEX\_E INDEX\_D + SIZE\_D

INDEX\_A
INDEX\_B
INDEX\_C
INDEX\_D
INDEX\_E

INDEX\_A \* INDEX\_A
INDEX\_B \* INDEX\_B
INDEX\_C \* INDEX\_C
INDEX\_D \* INDEX\_D
INDEX\_E \* INDEX\_E

ergibt

# 1 ""
# 1 ""
# 1 ""
# 1 ""
# 12 ""
0
0 + 13
0 + 13 + 8
0 + 13 + 8 + 2
0 + 13 + 8 + 2 + 10

0 \* 0
0 + 13 \* 0 + 13
0 + 13 + 8 \* 0 + 13 + 8
0 + 13 + 8 + 2 \* 0 + 13 + 8 + 2
0 + 13 + 8 + 2 + 10 \* 0 + 13 + 8 + 2 + 10

also

INDEX_A = 0
INDEX_B = 13
INDEX_C = 21
INDEX_D = 23
INDEX_E = 33

INDEX_A * INDEX_A = 0
INDEX_B * INDEX_B = 13
INDEX_C * INDEX_C = 34
INDEX_D * INDEX_D = 44
INDEX_E * INDEX_E = 56

Dagegen helfen würden Klammern.

Gruß
Diether

Hallo.
http://ideone.com/HJrSj
Ja.
Liebe Grüße.
Alex

Hallo Lutz,

Hast Du es mal ausprobiert?

nein, der Compiler ist nicht auf meinem Rechner.

… da findet keine Zuweisung statt.

Ja da habe ich mich falsch ausgedrückt.

Danke, Robert :smile:

Hi!

Verstehe, wenn ich es also folgendermaßen schreibe:

#define INDEX_A 0
#define INDEX_B (INDEX_A + SIZE_A)
#define INDEX_C (INDEX_B + SIZE_B)
#define INDEX_D (INDEX_C + SIZE_C)
#define INDEX_E (INDEX_D + SIZE_D)

bin ich auf der sicheren Seite.

Danke Dir. Robert.

Hi Alex

vielen Dank das Du die die Mühe gemacht hast. Wie ich unten schon
schrieb habe ich den Compiler nicht bei mir, das gestaltet dann alles
etwas schwieriger. Bzgl Code muss man noch aufpassen das man nicht in die „Makrofalle“ tappt, vgl. Diethers Post.

Grüße, Robert

Hallo Robert,

Verstehe, wenn ich es also folgendermaßen schreibe:
#define INDEX_A 0
#define INDEX_B (INDEX_A + SIZE_A)
#define INDEX_C (INDEX_B + SIZE_B)
#define INDEX_D (INDEX_C + SIZE_C)
#define INDEX_E (INDEX_D + SIZE_D)
bin ich auf der sicheren Seite.

ja, da die Klammer oberste Priorität hat wird damit vermieden, dass die Addition ungewünscht durchgeführt wird.

Gruß
Diether

bin ich auf der sicheren Seite.

ja, da die Klammer oberste Priorität hat wird damit vermieden,
dass die Addition ungewünscht durchgeführt wird.

Hallo Diether,

wenn schon, denn schon:

#define INDEX_B ((INDEX_A) + (SIZE_A))

Schließlich hast Du das Problem ja nach außen und innen. Einmal, weil Du nicht vom Kontext abhängig sein willst, in dem INDEX_B nach außen verwendet wird, noch wie die Bezeichner innen definiert sind.

Wenn man natürlich nur eigene Bezeichner verwendet, reicht es, die Klammern nur außen zu verwenden. Bei Variablen notwendig und grundsätzlich sicherer ist es natürlich beides zu tun, da daraus ja kein Nachteil entsteht - außer minimaler Verschlechterung der Lesbarkeit.
Ich würde es allerdings als Codierfehler ansehen, wenn jemand einen ungeklammerten Term als Ersatz und ungeklammerte Variablen verwendet.

Insgesamt gehört #define zu den Dingen, die man in C++ besser durch inline und const ersetzt. Denn spätestens beim In-/Dekrement knallt es trotz Klammer. Das sind dann die Fälle, in denen man tagelang nach Fehlern sucht. Was Compiler daraus machen ist nicht festgelegt:

#define ABS(x) (((x)>0)?(x):frowning:-(x)))

while (ABS(++i)

Ciao, Allesquatsch

2 Like