[Solved] Unroll a loop using a macro that has a goto and a label in it


You really should make it a dowhile loop:

#define BROP(num, sum)  do{                \
   bool again = false;                     \
   num = rand_lcg(generated);              \
   if (num % 2)  {                         \
   do { again = false;                     \
     generated = rand_lcg(generated);      \
     if (generated < 512)                  \
           sum -= generated;               \
     else                                  \
        again = true;                      \
   } while(again); } while(0)

See this for the old outerdo{}while(0) trick.

If you (wrongly) insist on having a label and are using the GCC compiler (or Clang/LLVM which should be compatible on that), you could use local labels extension (i.e. with __label__ …)

You might also generate the label from the __LINE__ number using concatenation in the preprocessor. Take inspiration from

#define STUPID_LOOP_BIS(Test,Lin) do { \
 lab##Lin: if (Test) goto lab##Lin; } while(0)
#define STUPID_LOOP_AT(Test,Lin) STUPID_LOOP_BIS(Test,Lin)
#define STUPID_LOOP(Test) STUPID_LOOP_AT(Test,__LINE__)

for obscure reasons you need all the three macros!

And use

  STUPID_LOOP(x++ < 100);
  STUPID_LOOP(y-- > 0);

on separate lines. Of course adapt and improve for your need.

You definitely should use and trust more the compiler optimization abilities and have static inline functions. Not every test is compiled to a machine branch (e.g. because of CMOV instructions); not every loop is compiled to a machine loop (e.g. because of loop unrolling). You are probably losing your developer’s time, and more importantly, you are disabling optimizations by your tricks (so your code will likely go slower, not faster).

If using GCC or Clang enable optimizations and warnings: so compile with
gcc -Wall -Wextra -O3 -mtune=native

2

solved Unroll a loop using a macro that has a goto and a label in it