# Compiler bug?

This topic is 3985 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Ok, having had my problems with *one* compiler bug (the compiler is VC++ 2005) yesterday (Which has apparently been solved by Microsoft, but the solution was only released with VS2008...), I seem to have found another one, but maybe I'm just overlooking something stupid I did... I have the following class (most stuff removed)
template<unsigned int N, unsigned int M, typename Scalar>
class mat
, boost::multiplicative2< mat<N,M,Scalar>, Scalar
, boost::equality_comparable< mat<N,M,Scalar>
> > >
{
public:
/*...*/

const vec<N,Scalar>& column(unsigned int j) const
{
assert(j < M);
return *(reinterpret_cast<const vec<N,Scalar>* >(&data[N*j]));
}

vec<N,Scalar>& column(unsigned int j)
{
assert(j < M);
return *(reinterpret_cast<vec<N,Scalar>* >(&data[N*j]));
}

/*...*/

private:
Scalar data[N*M]; // In column-major storage
};


and of course a corresponding vector class with all the usual operators etc. The following code (for computing a determinant) fails:
template<unsigned int N, typename Scalar, bool cond>
class det
{
public:
/* Gaussian elimination for large matrices */
static Scalar compute(const mat<N,N,Scalar>& a)
{
mat<N,N,Scalar> copy = a; /* Is it ok to allocate this on the stack? */
Scalar factor = 1;
unsigned int i = 0;
unsigned int j = 0;

while(i < N && j < N)
{
cout << copy << endl;
unsigned int maxj = j;
for(unsigned int k = j+1; k < N; ++k)
{
if(std::abs(copy(i,k)) > std::abs(copy(i,maxj)))
maxj = k;
}
if(copy(i,maxj) != 0)
{
/* Swap columns j and maxj */
vec<N,Scalar> temp = copy.column(j);
copy.column(j) = copy.column(maxj);
copy.column(maxj) = temp;

cout << "Swapped " << copy << endl;

if(j != maxj)
factor = -factor * copy(i,j);
else
factor = factor * copy(i,j);

copy.column(j) /= copy(i,j); /* why doesn't this work?? (only copy(i,j) is being updated) */
// copy.column(j) = copy.column(j) / copy(i,j); /* this on the other hand works */

cout << "Divided " << copy << endl;

for(unsigned int k = j+1; k < N; ++k)
copy.column(k) -= copy(i,k) * copy.column(j);

++i;
}
else /* Early out */
{
cout << "Early out" << endl;
return 0;
}
++j;
}

return factor;
}
};



##### Share on other sites
What do you mean by "The following code ... fails"?

Does it fail to compile? If so, what error message does the compiler give?
Does it crash at runtime? Is so, what error message do you get?
Does it fail to printthe correct results? If so, what does it print?

##### Share on other sites
I didn't mention it explicitly because it is already in the comments:

/*...*/copy.column(j) /= copy(i,j); /* why doesn't this work?? (only copy(i,j) is being updated) */// copy.column(j) = copy.column(j) / copy(i,j); /* this on the other hand works *//*...*/

1. no, it does not fail to compile
2. no, it does not crash at runtime
3. the results are incorrect, since only the element corresponding to copy(i,j) in copy.column(j) is really divided, the others are not.

##### Share on other sites
    copy.column(j) /= copy(i,j);

and
    copy.column(j) = copy.column(j) / copy(i,j);

use two different operators... I suspect they are overloaded in the vec class? The /= operator might not implemented properly (or not at all?).

##### Share on other sites
no, technically they use the same (i use boost::multiplicative2 for vec as well, which just creates a temporary vec, applies /= to the temporary vec and returns the temporary)

and it is defined as:

vec& operator/= (const Scalar& s){ for(unsigned int i = 0; i < N; ++i)  data /= s; return *this;}

Which is absolutely, 100%ly correct. (and it works everywhere else)

##### Share on other sites
fun fact:

if N is 4 and Scalar is float it works with both.
the only difference:
vec<4,float> is specialized and uses sse (which is what causes the other compiler bug to occur, although luckily only in debug builds), otherwise it is identical

and if i deactivate SSE (via a define), vec<4,float> operator /= is identical to the non-specialized version (the only difference are named accessors, and swizzle ops which are not used at that point), it *also* works

##### Share on other sites
never mind... i found the error. so this one is not a compiler bug...

##### Share on other sites
Quote:
 Original post by l0calh05tnever mind... i found the error. so this one is not a compiler bug...

Most of the time it is not the compiler.

##### Share on other sites
When you get really stuck on what seems to be (in your mind) a compiler bug, make a test case. That is, a MINIMAL piece of code that exhibits the problem. Usually in the process of doing so, you find the problem, if not, you allow other people to help understand the problem better to help you. If you haven't done that, you can't really blame the compiler yet. MSVC does have bugs though.

##### Share on other sites
Quote:
 Original post by CrypterMost of the time it is not the compiler.

Which is exactly why I asked here...

And yeah, VS has got some bugs, for example the one I encountered earlier (VS was misaligning an __m128 variable on the stack, but it only occurs in debug mode with inline template functions... very strange...)

1. 1
2. 2
3. 3
Rutin
14
4. 4
khawk
11
5. 5
• ### Forum Statistics

• Total Topics
633671
• Total Posts
3013269
×