compile time optimization problem

C

Carmine Cairo

Hi,

I'm working on a project and today I've note a little problem during the
compile fase.
Here a little piece of code:

// 1st version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) welldone++;
}
somethingelse = new someType[welldone];

if I try to compile and run this code, at the end of for loop the value
of welldone is ALWAYS 1 excepted when size is 0.
When I say ALWAY means really ALWAY even when it isn't the expected result.

Now, try to add a simple cout into a loop:

// 2nd version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) {
welldone++;
cout << "GREAT! Another welldone." << endl;
}
}
somethingelse = new someType[welldone];

now the welldone value is the expected one.

There's other problems.
In the first version p->getNextSomething() it's called ALWAYS one time
and the backbone vector isn't filled as well.

The standard say about the behaviour of compiler that can be optimize
the loop. When I put in the loop che cout the compiler can't act the
optimization (there's something to print). But why the compiler don't
"see" the use of i as index of a vector? And why the compiler don't
"see" the use of welldone for a future allocation?

Does something of you have encontered the same problem?
I use the GNU GCC as compiler. I try to use the -O0 flag but don't work.
Any suggest?

Thanks in advance
Carmine
 
V

Victor Bazarov

Carmine said:
I'm working on a project and today I've note a little problem during
the compile fase.

That doesn't seem right. If you didn't run it, how could have you
known that 'welldone' is always 1, regardless of the input? You had
to have run it to notice the problem.
Here a little piece of code:

// 1st version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) welldone++;
}
somethingelse = new someType[welldone];

if I try to compile and run this code, at the end of for loop the
value of welldone is ALWAYS 1 excepted when size is 0.


That means at least once 'backbone.error' equals 'NO_ERROR'.
When I say ALWAY means really ALWAY even when it isn't the expected
result.
Now, try to add a simple cout into a loop:

// 2nd version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) {
welldone++;
cout << "GREAT! Another welldone." << endl;
}
}
somethingelse = new someType[welldone];

now the welldone value is the expected one.


OK, I'll have to believe you, since the code is incomplete and you
don't even describe the input you're giving your program.
There's other problems.
In the first version p->getNextSomething() it's called ALWAYS one time
and the backbone vector isn't filled as well.

Sounds very much like a memory overrun. Undefined behavour of sorts.
The standard say about the behaviour of compiler that can be optimize
the loop.

Uh... What?
When I put in the loop che cout the compiler can't act the
optimization (there's something to print). But why the compiler don't
"see" the use of i as index of a vector? And why the compiler don't
"see" the use of welldone for a future allocation?

Erm... I don't know how to answer those questions. You seem pretty
convinced it's the compiler's fault. I cannot blindly accept that.
In 99.9% of cases when the programmer tries to blame the compiler, it
is his/her own fault.
Does something of you have encontered the same problem?

Something of us may have encountered some strangeness connected to the
behaviour of the optimizer, but there is no indication that it's what
you're experiencing.
I use the GNU GCC as compiler. I try to use the -O0 flag but don't
work. Any suggest?

Suggest: read FAQ 5.8.

Victor
 
P

Peter_Julian

| Hi,
|
| I'm working on a project and today I've note a little problem during
the
| compile fase.
| Here a little piece of code:
|
| // 1st version
| welldone = 0;

welldone doesn't exist.

| size = p->getSize();

size, p and getSize() don't exist.

| backbone = new rightType[size];

nothing on that line exists either. etc...

<snip>

| cout << "GREAT! Another welldone." << endl;

neither cout nor endl exist.

<snip>

| In the first version p->getNextSomething() it's called ALWAYS one time
| and the backbone vector isn't filled as well.

backbone is a vector? ok, a vector of what?

|
| The standard say about the behaviour of compiler that can be optimize
| the loop. When I put in the loop che cout the compiler can't act the
| optimization (there's something to print). But why the compiler don't
| "see" the use of i as index of a vector? And why the compiler don't
| "see" the use of welldone for a future allocation?

if backbone is a vector of integers, for example, then please help us
help you:

#include <iostream>
#include <ostream> // std::cout, std::endl
#include <iterator> // std::eek:stream_iterator
#include <algorithm> // std::copy(...)
#include <vector>

int main()
{
const int size(10); // modify to your heart's desire
std::vector< int > backbone;

for (int i = 0; i < size; ++i)
{
backbone.push_back( i ); // one element at a time
}
std::cout << "the vector's size = " << backbone.size();
std::cout << std::endl;

std::copy( backbone.begin(),
backbone.end(),
std::eek:stream_iterator<int>( std::cout, " ") );
std::cout << std::endl;

// now develop your question...
// C++ programmers are reknown for their poor guessing ability
// they even have a name for the disease: UB
return 0;
}

/*
the vector's size = 10
0 1 2 3 4 5 6 7 8 9

*/
 
J

John Harrison

Does something of you have encontered the same problem?
I use the GNU GCC as compiler. I try to use the -O0 flag but don't work.
Any suggest?

You have a bug in your code, don't blame the compiler, look for the bug.
The bug will be somewhere completely unexpected, perhaps in the
getNextSomething method.

john
 
C

Carmine Cairo

Victor said:
Carmine said:
I'm working on a project and today I've note a little problem during
the compile fase.

That doesn't seem right. If you didn't run it, how could have you
known that 'welldone' is always 1, regardless of the input? You had
to have run it to notice the problem.
Here a little piece of code:

// 1st version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) welldone++;
}
somethingelse = new someType[welldone];

if I try to compile and run this code, at the end of for loop the
value of welldone is ALWAYS 1 excepted when size is 0.


That means at least once 'backbone.error' equals 'NO_ERROR'.


I check it with debugger and with some cout inserted into code just for
debug information and I've also create an input ad hoc in witch all
backbone.error are equals to NO_ERROR.
When I say ALWAY means really ALWAY even when it isn't the expected
result.
Now, try to add a simple cout into a loop:

// 2nd version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) {
welldone++;
cout << "GREAT! Another welldone." << endl;
}
}
somethingelse = new someType[welldone];

now the welldone value is the expected one.


OK, I'll have to believe you, since the code is incomplete and you
don't even describe the input you're giving your program.


p is an istance of a class that menage a vector<string>, each element of
a vector give me some information about a protein structure.
Before the piece of code there are some setting for select the line I'm
interested to processing, something like this:
p->setAtomFilter("C");
p->setChainFilter("E");
etc...
rightType it's a sctructure that store 3D coordinate, an error flag, ad
other two minor things.
getNextSomething() return this structure refering to the next line that
match with the filter.
Sounds very much like a memory overrun. Undefined behavour of sorts.

Yes, it's the first think I've try to discover.
But every time I insert the cout all run done.
With the debbugger I try to discover some memory overrun but when I use
it the cicle it's performed size time and getNextSomething() it's called
size time. :-(
Uh... What?

if you write a for loop like this:
int i, k;
for (i = 0; i < 100; i++) {
k++;
}
the compiler optimize this loop and set directly i and k at 100 without
done any loop. It's a right choose, this loop can be serve only for CPU
cosuming time.
Erm... I don't know how to answer those questions. You seem pretty
convinced it's the compiler's fault. I cannot blindly accept that.
In 99.9% of cases when the programmer tries to blame the compiler, it
is his/her own fault.

I agree with you, I don't want blame the compiler, I'am try to know why
it have this behaviour with this code.
Today I've try to compile the code on a different version of g++ and it
work well.
The "wrong optimization" it's done when I use GCC 3.4.4 (cygwin special)
(gdc 0.12, using dmd 0.125).
The right run it's done when I use GCC version 3.3.5 (Debian
1:3.3.5-8ubuntu2)
Something of us may have encountered some strangeness connected to the
behaviour of the optimizer, but there is no indication that it's what
you're experiencing.


Suggest: read FAQ 5.8.

Thanks a lot.
Carmine
 
C

Carmine Cairo

The problem it's solved :)

no human error ed no machine error.
To try to proof the compiler error I start to write an equivalent piece
of code, then compile it and "see" what's happen.
The reason it's obviously the size of my code who is too much longer for
a complete post on this NG. But when I try to compile the smaller one it
worked perfectly. Then I try another time to compile my code but the
result don't change. With cout all work properly, without all fails.
Then I try to download and compile the code with C++ Builder and all
works fine.
Then I start to think really about a bug in g++ (I use the cygwin
version of g++). Then I remove from my hard drive the cygwin and
(re)install it completely. Then i retry to compile the original code and
now ALL WORK FINE.
So, no error in allocation mechanism, no memory overrun, and no error
was found on my code. No error and no bug it's present in g++ (cygwin
version) but only some undefined installation failure who caused this
strange behavior.

Now I'll come back to use the gnu-gcc package but if I see something
strange behavior ... I reinstall and retry :)

Thanks to all
Carmine


Carmine said:
Victor said:
Carmine said:
I'm working on a project and today I've note a little problem during
the compile fase.

That doesn't seem right. If you didn't run it, how could have you
known that 'welldone' is always 1, regardless of the input? You had
to have run it to notice the problem.
Here a little piece of code:

// 1st version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) welldone++;
}
somethingelse = new someType[welldone];

if I try to compile and run this code, at the end of for loop the
value of welldone is ALWAYS 1 excepted when size is 0.


That means at least once 'backbone.error' equals 'NO_ERROR'.


I check it with debugger and with some cout inserted into code just for
debug information and I've also create an input ad hoc in witch all
backbone.error are equals to NO_ERROR.
When I say ALWAY means really ALWAY even when it isn't the expected
result.
Now, try to add a simple cout into a loop:

// 2nd version
welldone = 0;
size = p->getSize();
backbone = new rightType[size];
p->rewind();
for (int i = 0; i < size; i++) {
backbone = p->getNextSomething();
if(backbone.error == NO_ERROR) {
welldone++;
cout << "GREAT! Another welldone." << endl;
}
}
somethingelse = new someType[welldone];

now the welldone value is the expected one.


OK, I'll have to believe you, since the code is incomplete and you
don't even describe the input you're giving your program.


p is an istance of a class that menage a vector<string>, each element of
a vector give me some information about a protein structure.
Before the piece of code there are some setting for select the line I'm
interested to processing, something like this:
p->setAtomFilter("C");
p->setChainFilter("E");
etc...
rightType it's a sctructure that store 3D coordinate, an error flag, ad
other two minor things.
getNextSomething() return this structure refering to the next line that
match with the filter.
Sounds very much like a memory overrun. Undefined behavour of sorts.

Yes, it's the first think I've try to discover.
But every time I insert the cout all run done.
With the debbugger I try to discover some memory overrun but when I use
it the cicle it's performed size time and getNextSomething() it's called
size time. :-(
Uh... What?

if you write a for loop like this:
int i, k;
for (i = 0; i < 100; i++) {
k++;
}
the compiler optimize this loop and set directly i and k at 100 without
done any loop. It's a right choose, this loop can be serve only for CPU
cosuming time.
Erm... I don't know how to answer those questions. You seem pretty
convinced it's the compiler's fault. I cannot blindly accept that.
In 99.9% of cases when the programmer tries to blame the compiler, it
is his/her own fault.

I agree with you, I don't want blame the compiler, I'am try to know why
it have this behaviour with this code.
Today I've try to compile the code on a different version of g++ and it
work well.
The "wrong optimization" it's done when I use GCC 3.4.4 (cygwin special)
(gdc 0.12, using dmd 0.125).
The right run it's done when I use GCC version 3.3.5 (Debian
1:3.3.5-8ubuntu2)
Something of us may have encountered some strangeness connected to the
behaviour of the optimizer, but there is no indication that it's what
you're experiencing.


Suggest: read FAQ 5.8.

Thanks a lot.
Carmine
 

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

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top