相关疑难解决方法(0)

为什么在宏中使用明显无意义的do-while和if-else语句?

在许多C/C++宏中,我看到宏的代码包含在看似无意义的do while循环中.这是一些例子.

#define FOO(X) do { f(X); g(X); } while (0)
#define FOO(X) if (1) { f(X); g(X); } else
Run Code Online (Sandbox Code Playgroud)

我看不出它do while在做什么.为什么不在没有它的情况下写这个?

#define FOO(X) f(X); g(X)
Run Code Online (Sandbox Code Playgroud)

c c++ c++-faq c-preprocessor

758
推荐指数
8
解决办法
9万
查看次数

C多行宏:do/while(0)vs scope block

可能的重复:
当我们定义一个宏时,do(0)有什么用?
为什么在C/C++宏中有时会出现无意义的do/while和if/else语句?
做{...}而(0)有什么好处?

我已经看到一些包含在do/while(0)循环中的多行C宏,如:

#define FOO \
  do { \
    do_stuff_here \
    do_more_stuff \
  } while (0)

与使用基本块相反,以这种方式编写代码有什么好处(如果有的话):

#define FOO \
  { \
    do_stuff_here \
    do_more_stuff \
  }

c macros multiline

173
推荐指数
1
解决办法
10万
查看次数

当我们定义宏时,do while(0)有什么用?

可能重复:
C/C++宏中的Do-while和if-else语句

我正在阅读linux内核,我发现了很多像这样的宏:

#define INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
Run Code Online (Sandbox Code Playgroud)

为什么他们使用这个而不是简单地在{}中定义它?

c macros linux-kernel

125
推荐指数
2
解决办法
5万
查看次数

"打破;" 出于"if"声明?

你能否突破if语句或是否会导致崩溃?我开始熟悉C,但这似乎有争议.第一张图片来自C上的一本书("Head First C"),该片段显示的是哈佛大学CS班级工作人员编写的代码.究竟是怎么回事并且与C标准有关?

如果陈述,休息不会破坏.

1990年1月15日,AT&T的长途电话系统崩溃,6万人失去了电话服务.原因?处理交换机中使用的C代码的开发人员试图使用a break来打破if声明.但是break,不要突破ifs.相反,该程序跳过了整段代码,并引入了一个错误,该错误在9个小时内中断了7000万个电话.

for (size = 0; size < HAY_MAX; size++)
{
    // wait for hay until EOF
    printf("\nhaystack[%d] = ", size);
    int straw = GetInt();
    if (straw == INT_MAX)
        break;

    // add hay to stack
    haystack[size] = straw;
}
printf("\n");
Run Code Online (Sandbox Code Playgroud)

c

31
推荐指数
1
解决办法
11万
查看次数

你认为这种技术"不好"吗?

有时您需要在某些非严重错误条件下跳过方法的一部分.您可以使用异常,但通常不建议在正常应用程序逻辑中使用异常,仅针对异常情况.

所以我做了这样的伎俩:

do
{
   bool isGood = true;

   .... some code

   if(!isGood)
       break;

   .... some more code

   if(!isGood)
       break;

   .... some more code

 } while(false);

 ..... some other code, which has to be executed.
Run Code Online (Sandbox Code Playgroud)

我使用一个"假"循环,它将运行一次,我可以通过中断或继续中止它.

我的一些同事不喜欢这样,他们称之为"不良做法".我个人觉得这个方法很漂亮.但你怎么看?

c++ coding-style

21
推荐指数
8
解决办法
1万
查看次数

为什么使用这个结构?疯狂还是天才?

我正在使用从Linus Torvalds到不明身份的Elbonian代码奴隶的各种不同质量/能力/理智来源的大型SDK代码库.

有各种各样的代码风格,有些明显优于其他代码,并且它证明了一个有趣的机会,可以通过其他措施扩展我对人类未来的知识/绝望.

我刚刚遇到一堆函数,它们反复使用一种略微奇怪的(对我来说)风格,即:

void do_thing(foo)
{
    do {
        if(this_works(foo) != success)
            break;
        return(yeah_cool);
    } while (0);
    return(failure_shame_death);
}
Run Code Online (Sandbox Code Playgroud)

在这段代码中没有做任何复杂的事情(我没有为这篇文章剪掉10,000行魔法),他们可以轻松地做到:

if(this_works(foo) == success)
    return(yeah_cool);
else
    return(failure_shame_death);
Run Code Online (Sandbox Code Playgroud)

这似乎更好/更整洁/更直观/更容易阅读.

所以我现在想知道是否有一些(好的)理由以另一种方式做到这一点,还是只是他们总是在Elbonian Code Mines中这样做的方式?

编辑:根据"可能的重复"链接,此代码不会在任何类型的宏中进行预处理,它只是在普通代码中.我可以相信这可能是由于关于错误检查的编码样式规则,根据这个答案.

c coding-style

17
推荐指数
3
解决办法
614
查看次数

在C宏中使用和返回输出

我正在尝试检测一些代码来捕获和打印错误消息.目前我正在使用像这样的宏:

#define my_function(x) \
  switch(function(x)) { \
    case ERROR: \
      fprintf(stderr, "Error!\n"); \
      break; \
  }
Run Code Online (Sandbox Code Playgroud)

通常,我从不捕获函数输出,这很好.但我发现了几个我需要返回值的情况function().我试过类似下面的内容,但这会产生语法错误.

#define my_function(x) \
  do { \
    int __err = function(x); \
    switch(__err) { \
      case ERROR: \
        fprintf(stderr, "Error!\n"); \
        break; \
    } \
    __err; \
  } while(0)
Run Code Online (Sandbox Code Playgroud)

我可以声明一个全局变量来保存函数的返回值,但这看起来很难看,我的程序是多线程的,所以这可能会导致问题.我希望那里有更好的解决方案.

c return-value c-preprocessor

13
推荐指数
3
解决办法
5万
查看次数

宏中的do {} while(0)与({})的优点是什么?

Stack Overflow关于do { ... } while(0)宏的使用有很多问题,但这有点不同.我理解为什么do { ... } while(0)用于在宏扩展中包装多行代码.但是我经常看到另一种形式:({ ... }).

该({ })表单的优点是它是一个表达式并且可以具有"返回值".它(主观地)读取也好于do { } while(0).那为什么不总是使用它?do { } while(0)相反,在宏中使用有什么优势?

c macros

13
推荐指数
1
解决办法
530
查看次数

C:做{...}而(0)?

可能重复:
为什么在C/C++宏中有时会出现无意义的do/while和if/else语句?
做{...}而(0)有什么好处?

我正在研究一些充满宏的C代码,如下所示:

#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释这个宏的作用,为什么do {} while(0)需要?那只是执行一次代码吗?

c macros

9
推荐指数
2
解决办法
4888
查看次数

为什么写C代码如"while((void)0,0)"

我从opencv的源代码中读到它

#define IPP_FILTER_MEDIAN_BORDER(ippType, ippDataType, flavor) \
    do \
    { \
        if (ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, \
            ippDataType, CV_MAT_CN(type), &bufSize) >= 0) \
        { \
            Ipp8u * buffer = ippsMalloc_8u(bufSize); \
            IppStatus status = ippiFilterMedianBorder_##flavor(src.ptr<ippType>(), (int)src.step, \
                dst.ptr<ippType>(), (int)dst.step, dstRoiSize, maskSize, \
                ippBorderRepl, (ippType)0, buffer); \
            ippsFree(buffer); \
            if (status >= 0) \
            { \
                CV_IMPL_ADD(CV_IMPL_IPP); \
                return; \
            } \
        } \
        setIppErrorStatus(); \
    } \
    while ((void)0, 0)
Run Code Online (Sandbox Code Playgroud)

我可以理解while(0)在这里,但为什么要添加"(void)0".

c opencv

9
推荐指数
1
解决办法
792
查看次数