0

I'm trying to compile LightZPng with warnings on level 4. I get a lot of C4127 on lines that are clearly not worthy of this warning. An example:

#define MAX_BITS 15
int values_per_bitlen[ MAX_BITS + 1 ];
for ( int i = 0; i <= MAX_BITS; ++i )    // C4127 is here
    values_per_bitlen[ i ] = 0;

How can this code be changed to avoid the warning other than #pragma?

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
Jim Buck
  • 20,482
  • 11
  • 57
  • 74

4 Answers4

4

There's a piece of code at the top of LightZ.cpp that goes like this:

#define for if (false) {} else for

That means your actual statement is:

#define for if (false) {} else for ( int i = 0; i <= MAX_BITS; ++i )

which is why you're getting the constant expression error (it's the false, not the i <= MAX_BITS as I thought).

Simply comment out or delete that line from the file (I can't actually figure out why they would do that).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Windows programmer
  • 7,871
  • 1
  • 22
  • 23
  • Good catch, @WinProg, fleshed it out for you and +1'ed it. – paxdiablo Jun 12 '09 at 03:45
  • Maybe this needs a further explanation? This causes every subsequent occurence of the token for to expand to an if statement containing a for statement. VC++ diagnoses if (false) as having a constant conditional expression, well no kidding. If you delete this line there will be fewer occurences of if (false) in the program. – Windows programmer Jun 12 '09 at 03:46
  • We were typing at the same time. Sorry if my comment looks insulting. – Windows programmer Jun 12 '09 at 03:47
  • No probs, I have pretty thick skin. – paxdiablo Jun 12 '09 at 03:49
  • What, awesome catch. I didn't consider a #define since my syntax highlighting still marked it as a keyword (I guess that takes precedence in syntax highlighting). – Jim Buck Jun 12 '09 at 04:08
  • 2
    The reason for the "#define for" is that older versions of Visual Studio had broken variable scoping in for loops: if you said for(int i = 0; ...), the variable "int i" would still be in alive after the loop was over. The #define adds an extra level of scope, fixing the problem, so that code that does "for(int i = 0; ...) ...; for(i = 0; ...)" no longer compiles (as it rightly shouldn't). – Adam Rosenfield Jun 12 '09 at 04:29
  • 2
    See http://stackoverflow.com/questions/984878/what-is-the-possible-use-for-define-for-if-false-else-for for more info. – paxdiablo Jun 12 '09 at 08:24
  • 1
    If I recall correctly, older versions of the C++ language defined the scope of the for variable exactly that way. – Windows programmer Jun 15 '09 at 02:20
1

Yes, that its odd. It's truly not a constant expression since i changes in the loop. So this would appear to be a problem with VS2005. For what it's worth, VS2008 does exactly the same thing.

Strangely enough, a project with just this in it does not complain so it may well be some weird edge-case problem with Microsoft's warning generation code:

#define MAX_BITS 15
int values_per_bitlen[ MAX_BITS + 1 ];
int main(int argc, char* argv[]) {
    for ( int i = 0; i <= MAX_BITS; ++i )
        values_per_bitlen[ i ] = 0;
    return 0;
}

However, you haven't actually asked a question. What is it that you want to know, or want us to do?

Update:

See "Windows programmer"'s answer for the actual cause - there's a "#define for if (false) {} else for" at the top of LightZ.cpp which is causing the problem.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

I tested it on my VS2005 and the warning does not appear, even at warning level 4. .

A simple procedure for you to follow :

-Create a new Console App and place only the above code and see if the warning shows up again.

-If not, check for differences in the project settings.

-If yes, I would assume that your optimization setting may be causing it.

Wartin
  • 1,965
  • 5
  • 25
  • 40
  • Yeah sure, some project settings tell VC++ to check for stuff like if (false), and some project settings tell VC++ not the check for stuff like if (false). – Windows programmer Jun 12 '09 at 03:32
0

According to Charles Nicholson, Visual Studio 2005 gives this error with the "do...while(0)" trick:

#define MULTI_LINE_MACRO \
    do { \
        doSomething(); \
        doSomethingElse(); \
    } while(0)

If you absolutely must, you can use the __pragma directive to selectively disable that warning around a particular code fragment.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589