Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

improper code generated by /O3 with "windows.h"

nupshur
Beginner
354 Views

Hi,

The following code did not compile correctly with the /O3, but did compile correctly with /O2:

#include

#include

"windows.h"

#include

#include

"a.h"

namespace

{

struct bT {

float a4; float a5;

};

const int stripSize = 4;

float a1[65536];

float a2[65536];

float a3[65536];

float a4[65536];

float a5[65536];

float a6[65536];

}

void

A::test() {

float tot = 0;

bar();

for (int i = 0; i < 1; ++i) {

tot += foo();

}

cout << tot << endl;

}

float

A::foo()

{

float tot = 0;

bT b[stripSize];

int numIncl;

for (int j = 0; j < 8; j+=stripSize) {

numIncl = 0;

for (int i = j; i < min(8, j+stripSize); ++i) {

b[numIncl].a4 = a4;

b[numIncl].a5 = a4[i;

numIncl++;

}

for (int k = 0; k < numIncl; ++k) {

tot += (b.a4 + b.a5);

}

}

return tot;

}

void

A::bar()

{

for (int i = 0; i <8; ++i) {

a1 = exp(i / 2000.f);

a2 = exp(i / 3000.f);

a3 = exp(i / 4000.f);

a4 = exp(i / 5000.f);

a5 = exp(i / 6000.f);

a6 = exp(i / 7000.f);

}

}

It took me many, many hours to figure out that this was because #define NOMINMAX did no t appear before the include files. Maybe people already know to always do this when including windows.h, butI didn't. Might be worth a mention in some documentation somewhere.

~Nafis

0 Kudos
2 Replies
Dale_S_Intel
Employee
354 Views

Thanks for the info, but I'm still a little confused. When you say it didn't "compile correctly", do you mean that the compile failed and gave some sort of error? Or do you mean that the resulting code did not work as expected?

As I understand it, "NOMINMAX" tells windows.hnot to define the macros for min/max. I would not expectthat to causedifferent behavior at -O2vs. -O3, so there could be a bug lurking somewhere. If you could provide more info and a complete test case (the test above is at least missing 'a.h'), I'd be happy to look into it more.

Thanks!

Dale

0 Kudos
nupshur1
Beginner
354 Views

Sorry that I was unclear. The compiler actually generates incorrect code. Here are the

missing files:

/***A.h****/

//#define NOMINMAX

#include

#include

"windows.h"

#include

using

namespace std;

class

A {

public

:

void test();

private

:

void bar();

virtual float foo();

};

/********************************/

/********A.cpp *******************/

#include

"a.h"

namespace

{

struct bT {

float a4; float a5;

};

const int stripSize = 4;

float a1[65536];

float a2[65536];

float a3[65536];

float a4[65536];

float a5[65536];

float a6[65536];

}

void

A::test() {

float tot = 0;

bar();

for (int i = 0; i < 1; ++i) {

tot += foo();

}

cout << tot << endl;

}

float

A::foo()

{

float tot = 0;

bT b[stripSize];

int numIncl;

for (int j = 0; j < 8; j+=stripSize) {

numIncl = 0;

for (int i = j; i < min(8, j+stripSize); ++i) {

b[numIncl].a4 = a4;

// + a2 + a3 + a4 + a5 + a6 ;

b[numIncl].a5 = a4;

// * a2 * a3 * a4 * a5 * a6 ;

numI ncl++;

}

for (int k = 0; k < numIncl; ++k) {

tot += (b.a4 + b.a5);

}

}

return tot;

}

void

A::bar()

{

for (int i = 0; i <8; ++i) {

a1 = exp(i / 2000.f);

a2 = exp(i / 3000.f);

a3 = exp(i / 4000.f);

a4 = exp(i / 5000.f);

a5 = exp(i / 6000.f);

a6 = exp(i / 7000.f);

}

}

/*******************************************/

/*******************tmp.cc******************/

#include

#include

"windows.h"

#include

"a.h"

int

main ()

{

A a;

a.test();

}

/*******************************************/

If you uncomment the line #define NOMINMAX in A.h or compile with /O2 instead of /O3, the correct code will be generated.

~Nafis

0 Kudos
Reply