]> git.draconx.ca Git - dxcommon.git/commitdiff
xtra: Avoid undefined ## usage.
authorNick Bowler <nbowler@draconx.ca>
Mon, 23 Jan 2023 04:34:16 +0000 (23:34 -0500)
committerNick Bowler <nbowler@draconx.ca>
Mon, 23 Jan 2023 05:05:47 +0000 (00:05 -0500)
According to the C spec, every use of the ## operator has to produce a
valid preprocessing token, otherwise the behaviour is undefined.  It is
not enough to merely ensure that a sequence of ## operators results in
a valid token at the end.

This matters in practice, as at least some versions of the Sun Studio
compiler will turn:

  #define PASTE(a, b) a ## b
  #define PASTE2(a, b) PASTE(a, b)

  PASTE2(uint_least, PASTE(8, _t))

into two tokens:

  uint_least8 _t

instead of uint_least8_t as desired.  The results are not good for
the XTRA_PACKED_LOPTS macro.  Fortunately, it is straightforward to
rearrange the expansions to avoid this problem.

src/xtra.h

index 4de8df53f9cd436d7cbb108b248c5e7dd47d9b1d..1296321ff8777d64e0c94e878216ee62aa3f8f54 100644 (file)
@@ -30,7 +30,7 @@
  * The uint_leastXX_t typedefs must be in scope in order to use this macro.
  */
 #define XTRA_PACKED_LOPTS(name) \
-       static const XTRA_PASTE2(uint_least, XTRA_PASTE2(LOPT_PACK_BITS2, _t)) \
+       static const XTRA_PASTE2(XTRA_PASTE2(uint_least, LOPT_PACK_BITS2), _t) \
                name##_packed[] = { LOPTS_PACKED_INITIALIZER }; \
        struct option name[XTRA_ARRAYSIZE(name##_packed) + 1] = {0}; \
        do { \