|
C's macros are primitive and unsafe but by no means useless. Here's a somewhat silly example from embedded programming. I wanted to embed the bitmaps of a small set of characters for use on a bitmapped monochrome display. It was easy to define macros CHAR_GRID, _ and X such that e.g. const uint8_t zero[] = {
CHAR_GRID(
_,X,X,X,_,
X,_,_,_,X,
X,_,_,X,X,
X,_,X,_,X,
X,X,_,_,X,
X,_,_,_,X,
_,X,X,X,_
)
};
desugared to a column-major array of 5 bytes. #define CHAR_GRID(c1r1, c2r1, c3r1, c4r1, c5r1, \
c1r2, c2r2, c3r2, c4r2, c5r2, c1r3, c2r3, c3r3, c4r3, c5r3, c1r4, c2r4, c3r4, c4r4, c5r4, c1r5, c2r5, c3r5, c4r5, c5r5, c1r6, c2r6, c3r6, c4r6, c5r6, c1r7, c2r7, c3r7, c4r7, c5r7) \
c1r1 | (c1r2 << 1) | (c1r3 << 2) | (c1r4 << 3) | (c1r5 << 4) | (c1r6 << 5) | (c1r7 << 6), \
c2r1 | (c2r2 << 1) | (c2r3 << 2) | (c2r4 << 3) | (c2r5 << 4) | (c2r6 << 5) | (c2r7 << 6), \
c3r1 | (c3r2 << 1) | (c3r3 << 2) | (c3r4 << 3) | (c3r5 << 4) | (c3r6 << 5) | (c3r7 << 6), \
c4r1 | (c4r2 << 1) | (c4r3 << 2) | (c4r4 << 3) | (c4r5 << 4) | (c4r6 << 5) | (c4r7 << 6), \
c5r1 | (c5r2 << 1) | (c5r3 << 2) | (c5r4 << 3) | (c5r5 << 4) | (c5r6 << 5) | (c5r7 << 6)
|