使用包含goto和标签的宏展开循环 这个问题与C语言或C++语言的能力严格相关。我不推荐以下代码作为设计模式。我不使用它,也不鼓励它。但我只是想提高我的知识
我有一个包含标签和转到条件的定义使用包含goto和标签的宏展开循环 这个问题与C语言或C++语言的能力严格相关。我不推荐以下代码作为设计模式。我不使用它,也不鼓励它。但我只是想提高我的知识,c++,c,compiler-errors,C++,C,Compiler Errors,我有一个包含标签和转到条件的定义 #define BROP(num, sum) \ num = rand_lcg(generated); \ if (num % 2) \ { \ rng1: \ generated = rand_lc
#define BROP(num, sum) \
num = rand_lcg(generated); \
if (num % 2) \
{ \
rng1: \
generated = rand_lcg(generated); \
if (generated < 512) \
sum -= generated; \
else \
goto rng1; \
}
#定义BROP(num,sum)\
num=随机数(已生成)\
如果(数量%2)\
{ \
rng1:\
已生成=随机成本(已生成)\
如果(生成<512)\
总和-=生成的\
否则\
后藤rng1\
}
在后面的代码中,我这样使用它:
for (i = 0; i < iterations; i++)
{
BROP(num, sum);
BROP(num, sum);
BROP(num, sum);
// ...
}
for(i=0;i
我最终会遇到这样的情况:循环被展开,标签被重新定义
是否有一个智能构造可以让编译器在每次定义“实例化”时重命名标签
我知道避免这句话的所有选择,但我仍然不知道问题的答案。你真的应该把它变成
do
…而循环:
#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)
由于不清楚的原因,您需要所有这三个宏
和使用
STUPID_LOOP(x++ < 100);
STUPID_LOOP(y-- > 0);
dumby_循环(x++<100);
愚蠢的_循环(y-->0);
在不同的线路上。当然,根据您的需要进行调整和改进
您肯定应该更多地使用和信任编译器优化功能,并拥有静态内联函数。并非每个测试都编译到机器分支(例如,因为);并非每个循环都编译为机器循环(例如,因为)。您可能正在浪费开发人员的时间,更重要的是,您正在通过技巧禁用优化(因此您的代码可能会变慢,而不是变快)
如果使用GCC或Clang启用优化和警告:那么使用GCC-Wall-Wextra-O3-mtune=native编译,忽略它的原因,以下版本的BROP
将干净地编译为C和C++
#define BROP(num, sum, lbl) \
num = rand_lcg(generated); \
if (num % 2) \
{ \
lbl : \
generated = rand_lcg(generated); \
if (generated < 512) \
sum -= generated; \
else \
goto lbl; \
}
#定义BROP(num、sum、lbl)\
num=随机数(已生成)\
如果(数量%2)\
{ \
lbl:\
已生成=随机成本(已生成)\
如果(生成<512)\
总和-=生成的\
否则\
goto lbl\
}
我把它当作
for (i = 0; i < 1000; i++)
{
BROP(num,sum, lbl1);
BROP(num,sum, lbl2);
}
(i=0;i<1000;i++)的
{
BROP(num,sum,lbl1);
BROP(num,sum,lbl2);
}
这不依赖于任何编译器扩展,因此您应该能够在大范围的编译器中使用它。是否有理由不能在宏中使用do-while
循环构造而不是goto
。。。为什么这不是函数?C还是C++?他们是不同的语言!这如何避免分支?每个if
语句都会生成一个分支,这会使编译器更难为您进行优化。@VAndrei,这真是一个糟糕的策略。标签是用来引导人们回答他们感到舒服的问题的。有没有理由不将循环条件更改为while(生成<512)
而不是使用单独的bool
变量?while(再次);添加一个分支?除了我显式编写的分支外,我的代码中不需要任何额外的分支。通过预处理器串联和\uuuuuuuuuuuuuuuuu
它仍然是可移植的,并且您不必手动发明lbl2
标签!同意,但我要的是最简单的解决方案。我怀疑这是为了基准测试或测试套件,所以明确的选择通常是更好的选择。
for (i = 0; i < 1000; i++)
{
BROP(num,sum, lbl1);
BROP(num,sum, lbl2);
}