views:

530

answers:

4

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?

+1  A: 

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
Added a question.. just basically want to change the code to avoid the warning without actually turning off the warning.
Jim Buck
You want to change the code? Delete the line that I quoted in my answer.
Windows programmer
+4  A: 

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).

Windows programmer
Good catch, @WinProg, fleshed it out for you and +1'ed it.
paxdiablo
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
We were typing at the same time. Sorry if my comment looks insulting.
Windows programmer
No probs, I have pretty thick skin.
paxdiablo
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
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
See http://stackoverflow.com/questions/984878/what-is-the-possible-use-for-define-for-if-false-else-for for more info.
paxdiablo
If I recall correctly, older versions of the C++ language defined the scope of the for variable exactly that way.
Windows programmer
A: 

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
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
A: 

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
It also gives that warning for if (false), as we've seen in this question.
Windows programmer