Skip to content

Commit

Permalink
ImportC: function-like macros
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Feb 19, 2024
1 parent 0437e7b commit e94207c
Showing 1 changed file with 63 additions and 7 deletions.
70 changes: 63 additions & 7 deletions spec/importc.dd
Original file line number Diff line number Diff line change
Expand Up @@ -227,22 +227,78 @@ $(H2 $(LNAME2 preprocessor, Preprocessor))
$(H3 $(LNAME2 defines, Preprocessor Macros))

$(P ImportC collects all the $(TT #define) macros from the preprocessor run when it is run automatically.
The macros that look like manifest constants, such as:)

$(CCODE
#define COLOR 0x123456
Some can be made available to D code by interpreting them as declarations.
The variety of macros that can be interpreted as D declarations may be expanded,
but will never encompass all the metaprogramming uses of C macros.
)

$(H4 Manifest Constants)

$(P Macros that look like manifest constants, such as:)

$(CCODE
#define COLOR 0x123456
#define HELLO "hello")

$(P are interpreted as D manifest constant declarations of the form:)

---
enum COLOR = 0x123456;
enum HELLO = "hello";
---

$(P The variety of macros that can be interpreted as D declarations may be expanded,
but will never encompass all the metaprogramming uses of C macros.
)
$(H4 Function-Like Macros)

$(P Many macros look like functions, and can be treated as template functions:)

$(CCODE
#define ABC a + b
#define DEF(a) (a + x)
)

---
auto ABC() { return a + b; }
auto DEF(T)(T a) { return a + x; }
---

$(P Some macro formulations, however, will not produce the same result:)

$(CCODE
#define ADD(a, b) a + b
int x = ADD(1, 2) * 4; // sets x to 9)

---
auto ADD(U, V)(U a, V b) { return a + b; }
int x = ADD(1, 2) * 4; // sets x to 12
---

$(BEST_PRACTICES Always use parenthesis around arguments and entire expressions:)

$(CODE
#define ADD(a, b) ((a) + (b))
)

$(P Another area of trouble is side effects in the arguments:)

$(CCODE
#define DOUBLE(x) ((x) + (x)))

---
int i = 0;
DOUBLE(i++);
assert(i == 2); // D result will be 1, C result will be 2
---

$(P and treating arguments as references:)

$(CCODE
#define INC(x) (++x))

---
int i = 0;
INC(i);
assert(i == 1); // D result will be 0, C result will be 1
---

$(H2 $(LNAME2 predefined-macros, Predefined Macros))

Expand Down

0 comments on commit e94207c

Please sign in to comment.