Endless Loop in C-Code when Using /Og

G

Guest

We are using Visual Studio .NET 2003. When using that compiler, the
following example code goes into an endless loop in the "while" loop when the
/Og optimization option is used:

#include <stdlib.h>
int resize(int *incsize, int min_size) {
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}
if ( min_size > 60 ) return 0;
else return min_size;
}
int main() {
int incsize = 10;
return resize(&incsize, 12);
}

The problem occurs when using a pointer and real value for the
multiplication in the while loop. It also requires some additional code
(other than just a return or print statement) after the loop.

To me, this looks like a compiler bug. I looked on Microsoft web site for
patches to Visual Studio .NET 2003 but I did not see any. Does anyone know
of a patch for this issue and if so, from where can I down load it?

Thanks,
 
P

Peter Oliphant

Hi Bev,

No solution for you here, but just a weird question here. Why is the while
loop there at all? The code would do exactly the same thing without it,
since it returns based only on the unchanged inputed parameter min_size (
incsize has no affect on the output exact possibly to hang in the while
loop). In fact, all the method resize() does is return '0' if min_size is
greater than 60, and min_size itself otherwise...

I'm guessing this is a simplification of your actual code, in which case I
understand that you're just boiling it down to a simpler thing that displays
the problem. But then why is the "if (m_size >60)..." code there, since it
is not part of the problem? In your example code the call to it should
return a 12 since 12 is less than or equal to 60...

[==P==]
 
G

Guest

That is an example program -- not the real thing. I pared out everything
that did not affect the bug.

Bev in TX
 
G

Guest

I should also have said that the real code reallocates memory after the loop
-- I just tried to remove everything that was complicated but still produce
the error.
 
A

aa

Bev in TX said:
We are using Visual Studio .NET 2003. When using that compiler, the
following example code goes into an endless loop in the "while" loop when
the
/Og optimization option is used:

#include <stdlib.h>
int resize(int *incsize, int min_size) {
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}
if ( min_size > 60 ) return 0;
else return min_size;
}
int main() {
int incsize = 10;
return resize(&incsize, 12);
}

The problem occurs when using a pointer and real value for the
multiplication in the while loop. It also requires some additional code
(other than just a return or print statement) after the loop.

To me, this looks like a compiler bug. I looked on Microsoft web site for
patches to Visual Studio .NET 2003 but I did not see any. Does anyone
know
of a patch for this issue and if so, from where can I down load it?

int incsize = 1;
incsize = (int) 1.25 * incsize;
if (incsize != 1)
{
std::cout << "I owe you a cup of coffe" << endl;
}
 
P

Peter Oliphant

I see that you're pointing out that IF 'incsize' is given a value of 1
initially it will stay 1, which would produce an infinite loop. HOWEVER, if
you look closer at her code you'll see she sets 'incsize' intially to 10, so
it shouldn't be an infinite loop... : )

[==P==]

PS - Loved the 'I owe you a cup of coffee' code... : )
 
T

Tom Serface

My guess is that it's an optimization bug. The compiler probably doesn't
reload the variable since it's in a tight loop and it's probably getting
tricked by the pointer. The OP might try doing something like:

#include <stdlib.h>
int resize(int *incsize, int min_size) {
int i = *incsize;

while(i <= min_size) {
i = (int)(i * 1.25);
}

if ( min_size > 60 )
return 0;
else
return min_size;
}

int main() {
int incsize = 10;
return resize(&incsize, 12);
}

However, what the OP did should work so I'm thinking this is the result of
an over zealous optimizer. Since the value of incsize really never changes
(just what it points to is being changed) the compiler probably removes the
check. This optimization is documented in the help.

Tom

Peter Oliphant said:
I see that you're pointing out that IF 'incsize' is given a value of 1
initially it will stay 1, which would produce an infinite loop. HOWEVER, if
you look closer at her code you'll see she sets 'incsize' intially to 10,
so it shouldn't be an infinite loop... : )

[==P==]

PS - Loved the 'I owe you a cup of coffee' code... : )

aa said:
int incsize = 1;
incsize = (int) 1.25 * incsize;
if (incsize != 1)
{
std::cout << "I owe you a cup of coffe" << endl;
}
 
G

Guest

As already noted, this tiny program was greatly simplified (to the point of
being stupid), because I only wanted to keep what causes the compilation
error to reveal itself. Even so there is no problem with the given data.

In the original code there is no danger of incsize being "1" -- the values
are much larger than what I put below (>10000).

Bev in TX
 
G

Guest

You are correct -- it should not go into an infinite loop. In fact, if I
build in debug mode or any optimizations except /Og, then the problem goes
away.

Peter Oliphant said:
I see that you're pointing out that IF 'incsize' is given a value of 1
initially it will stay 1, which would produce an infinite loop. HOWEVER, if
you look closer at her code you'll see she sets 'incsize' intially to 10, so
it shouldn't be an infinite loop... : )

[==P==]

PS - Loved the 'I owe you a cup of coffee' code... : )

aa said:
int incsize = 1;
incsize = (int) 1.25 * incsize;
if (incsize != 1)
{
std::cout << "I owe you a cup of coffe" << endl;
}
 
T

Tom Serface

Sounds like they will be doing some service packs:

http://www.microsoft-watch.com/article2/0,2180,1883868,00.asp

But I don't know if this particular problem will be addressed. My guess is
that this is a really tricky thing to fix for global optimization since it
would have to either never do the optimization or somehow monitory that data
each pointer points to. In your case, you are actually modifying the data
pointed to in the actual loop so that should be better. If it were being
modified outside of the loop (I.E., another thread) you'd probably want to
make it volatile so that optimizer would not, um, optimize it.

FWIW, I tried this same test with VC++ 2005 and it did not hang so it may be
something they fixed for this release. It is strange that when you set the
/Og option (in the Command Line box) it gives you the message:

cl : Command line warning D9035 : option 'Og' has been deprecated and will
be removed in a future release

:blush:)

Tom

Program I compiled:

// LoopTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;

int resize(int *incsize, int min_size)
{
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}

cout << "Done" << endl;
if ( min_size > 60 )
return 0;
else
return min_size;
}

int _tmain(int argc, _TCHAR* argv[])
{
int incsize = 10;
return resize(&incsize, 12);
}
 
B

beginthreadex

output to asm and check that. if your app is really small then finding your
code will be really simple because I think that your comments will be
pushed to the asm. so make comments, and output to asm. post here if you
need help reading it.
You are correct -- it should not go into an infinite loop. In fact, if I
build in debug mode or any optimizations except /Og, then the problem goes
away.

Peter Oliphant said:
I see that you're pointing out that IF 'incsize' is given a value of 1
initially it will stay 1, which would produce an infinite loop. HOWEVER,
if you look closer at her code you'll see she sets 'incsize' intially to
10, so it shouldn't be an infinite loop... : )

[==P==]

PS - Loved the 'I owe you a cup of coffee' code... : )

aa said:
We are using Visual Studio .NET 2003. When using that compiler, the
following example code goes into an endless loop in the "while" loop
when the
/Og optimization option is used:

#include <stdlib.h>
int resize(int *incsize, int min_size) {
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}
if ( min_size > 60 ) return 0;
else return min_size;
}
int main() {
int incsize = 10;
return resize(&incsize, 12);
}

The problem occurs when using a pointer and real value for the
multiplication in the while loop. It also requires some additional
code (other than just a return or print statement) after the loop.

To me, this looks like a compiler bug. I looked on Microsoft web site
for
patches to Visual Studio .NET 2003 but I did not see any. Does anyone
know
of a patch for this issue and if so, from where can I down load it?

int incsize = 1;
incsize = (int) 1.25 * incsize;
if (incsize != 1)
{
std::cout << "I owe you a cup of coffe" << endl;
}
 
R

Reginald Blue

Bev said:
We are using Visual Studio .NET 2003. When using that compiler, the
following example code goes into an endless loop in the "while" loop
when the /Og optimization option is used:

#include <stdlib.h>
int resize(int *incsize, int min_size) {
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}
if ( min_size > 60 ) return 0;
else return min_size;
}
int main() {
int incsize = 10;
return resize(&incsize, 12);
}

Use the volatile keyword. Fixes it instantly:

#include <stdlib.h>

int resize(volatile int *incsize, int min_size) {
while(*incsize <= min_size) {
*incsize = (int)(*incsize * 1.25);
}
if ( min_size > 60 ) return 0;
else return min_size;
}
int main() {
int incsize = 10;
return resize(&incsize, 12);
}


--
Reginald Blue
"I have always wished that my computer would be as easy to use as my
telephone. My wish has come true. I no longer know how to use my
telephone."
- Bjarne Stroustrup (originator of C++) [quoted at the 2003
International Conference on Intelligent User Interfaces]
 
T

Tom Serface

As noted in another newsgroup, this is also fixed in VC++ 2005, however it
warns that /Og has been deprecated so ...

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top