is `warning C4127` (conditional expression is constant) ever helpful?

前端 未结 2 1706
温柔的废话
温柔的废话 2020-12-20 12:32

While answering this post, I suggested using do {...} while(0) for multiline macros.

On MSVC, I found this code throws up:

warning C412         


        
2条回答
  •  伪装坚强ぢ
    2020-12-20 12:53

    A warning that a conditional expression is constant certainly can be useful. It can, in many cases, point to a logical error in your code.

    For example, if you write something like:

    if (x != NULL) { /* ... */ }
    

    where x is an array object, the expression is valid, but the expression x decays to a pointer to the array's initial element, which cannot be a null pointer. I don't know whether that produces the same error, but it's an example of the same kind of thing.

    Of course it isn't always useful. In your case, the

    do { /* ... */ } while (0)
    

    idiom is the best way to write a macro definition that's intended to be used in a context that requires a statement. Using while (0) in another context is likely to be a logical error [*].

    It's unfortunate that your compiler doesn't recognize it as a common idiom. Generating good warnings is tricky; the compiler has to go beyond the rules of the language and infer the programmer's intent.

    In this case, using some compiler-specific method to suppress the warning (as long as it doesn't break the code for other compilers) is probably the best approach. Using a command-line option to suppress the warning in all cases would be overkill; you could miss valid warnings elsewhere in your code.

    Apparently writing while (0,0) rather than while (0) avoids the warning. If you do that, you should add a comment clearly indicating that it's a workaround for your particular compiler. There's no particular reason a compiler shouldn't warn about while (0,0) or any other equivalent code.

    [*] It can make sense to write a do { /* ... */ } while (0) statement if you want to be able to use break to jump out of it.

提交回复
热议问题