You really should make it a do
…while
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