9

Possible Duplicate:
C/C++: How to use the do-while(0); construct without compiler warnings like C4127?

//file error.h

        #define FAIL(message) \
        do { \
            std::ostringstream ossMsg; \
            ossMsg << message; \
            THROW_EXCEPTION(ossMsg.str());\
        } while (false)


//main.cpp

...

FAIL("invalid parameters"); // <<< warning C4127: conditional expression is constant    

...

As you can see the warning is related to the do {} while(false).

I can only figure out the following way to disable the warning:

        #pragma warning( push )
        #pragma warning( disable : 4127 )
        FAIL("invalid parameters");
        #pragma warning( pop )

but I don't like this solution.

I also tried to put those macro in error.h without effect.

Any comments on how to suppress this warning in a decent way?

Thank you

Community
  • 1
  • 1
q0987
  • 34,938
  • 69
  • 242
  • 387
  • I'm sure you can pass command line arg to compiler – TJD Aug 20 '12 at 17:49
  • Summary: as answered in that other question, disable the warning. Not just locally with `#pragma warning`, but leave it disabled altogether. –  Aug 20 '12 at 17:50
  • Ok, but why not to leave just scope without `do...while`? – Lol4t0 Aug 20 '12 at 17:51
  • 7
    @Lol4t0 It's a common construct that makes `FAIL(...)` require an extra semicolon to form a full statement. It's to allow `if (...) FAIL(...); else` and have the `else` belong to the `if`. –  Aug 20 '12 at 17:52

2 Answers2

6

The warning is due to the while(false). This site gives an example of how to workaround this problem. Example from site (you'll have to re-work it for your code):

#define MULTI_LINE_MACRO_BEGIN do {  
#define MULTI_LINE_MACRO_END \  
    __pragma(warning(push)) \  
    __pragma(warning(disable:4127)) \  
    } while(0) \  
    __pragma(warning(pop))

#define MULTI_LINE_MACRO \  
        MULTI_LINE_MACRO_BEGIN \  
            std::printf("Hello "); \  
            std::printf("world!\n"); \  
        MULTI_LINE_MACRO_END  

Just insert your code between the BEGIN and END:

#define FAIL(message) \  
    MULTI_LINE_MACRO_BEGIN \  
        std::ostringstream ossMsg; \
        ossMsg << message; \
        THROW_EXCEPTION(ossMsg.str());\  
    MULTI_LINE_MACRO_END  
  • You really should not have a link as your answer. – Puppy Aug 20 '12 at 17:53
  • I got `error C2017: illegal escape sequence` for the usage of `__pragma`. MSVS 2010 cannot give it right. – q0987 Aug 20 '12 at 18:01
  • @q0987: Not sure why.. it's a valid keyword (http://msdn.microsoft.com/en-us/library/d9x1s805.aspx) –  Aug 20 '12 at 18:04
  • Yes, it is valid but the compiler complains and I saw similar posts through google – q0987 Aug 20 '12 at 18:11
  • 1
    @q0987: make sure there are no spaces or tabs after the `'\'` characters that are supposed to indicate line continuation. – Michael Burr Aug 20 '12 at 18:26
  • 2
    This is a better answer than the one in the duplicate. – Michael Burr Aug 20 '12 at 18:41
  • @MichaelBurr If the code is meant to be usable on other compilers too, it isn't. If the code is not meant to be used with anything other than VC++, opinions will still vary, but many people will agree with you. (Actually, this is one of the answers in the original already, although this has extra macros.) –  Aug 20 '12 at 18:53
1

1) Why not just THROW_EXCEPTION("invalid parameters")?
2) while(true) and break at the end?

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • +1 - I don't know why this got voted down, it is an easy and clean fix and if you put a comments in there explaining why you did it then it will be clear. – Caesar Aug 20 '12 at 18:24
  • @Caesar: Because it doesn't address the problem of using do/while(false) with multi-line processor directives and the associated warning. –  Aug 20 '12 at 18:28
  • @0A0D Maybe I miss understood the OP, but from my understanding is that he wanted a cleaner code. This is way cleaner then the example you gave and the functionality is the same. – Caesar Aug 20 '12 at 18:47
  • @Caesar: No, he wanted to know a better way to disable the warning without all the clutter, but still wanted the multi-line macro. –  Aug 20 '12 at 18:51
  • fwiw, I'm cool with the logic behind the downvote, but on the off-chance this helped the OP left it as an answer anyway. – djechlin Aug 20 '12 at 20:16
  • and this won't break in teh same way as just using scope blocks will? Edit - nevermind, while(true) has the same warning as while(false) – paulm Jun 09 '14 at 10:26