Jump to content
  • Advertisement
Sign in to follow this  
marshdabeachy

Visual C++ INTERNAL COMPILER ERROR

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay to start things off, this will likely make very little sense, because it was a struggle for me to get this working as far as I have. I'm getting an internal compiler error using Visual Studio .NET 2003. The specific error is this:
Quote:
c:\documents and settings\marshall\desktop\mode7\mode7.cpp(517): fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'f:\vs70builds\3077\vc\Compiler\Utc\src\P2\main.c', line 148)
The code it appears to be nuking on is this line inside the for loop:
std::list<Tween*>::iterator iter;
for (iter = p.tweens.begin(); iter != p.tweens.end(); iter++) {
	// loop through tweens using this vomit inducing code
	(p.*(*iter)->setProp)( (*iter)->tweenFunct(p.GetLifeCurrent(), p.GetLifeMax(), (*iter)->elements) );
}
Yeah, not exactly the prettiest code. It was working before I templatized it, though. Basically, I've set up a way to handle tweens over time. Looks like this:
template <class T>
struct Tween {
	T (*tweenFunct)(float life, float maxLife, std::vector<T>& elements);
	std::vector<T> elements;
	void (Sprite::*setProp)(T value);
};

template<class T>
void Particle::SetTransition(T (*tween)(float life, float maxLife, std::vector<T>& elements), void (Sprite::*setProp)(T value), T* element, int length) {
	// add tween to list
	Tween* t = new Tween;
	t->tweenFunct = tween;
	t->setProp = setProp;
	t->elements.resize(length);
	for (int i=0; i<length; i++) {
		t->elements = element;
	}
	tweens.push_back(t);
	// initialize property
	(this->*setProp)( (*tween)(1.0f, 1.0f, t->elements) );
}
Implementation looks like this:
unsigned elementsR[] = {0x00, 0xFF};
p->SetTransition(&LinearInTween<unsigned>, &Sprite::SetRed, elementsR, sizeof(elementsR));
It's a mess, I know. But the implementation is rather simple, and that's what I was going for. Previously, I had it passing the vectors by value, which was giving me a bizarre "cannot convert std::vector to std::vector" error. I switch it to pass by reference and now I'm getting an internal compiler error. If you somehow managed to understand this, do you have any idea what's going on, or more importantly, how to fix it? Many thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
I didn't read your code but is seems like you allocate too much memory some where there.
You allocate memory out of the limits of your compiler.
Try to read this article to understand more:
HERE

And wait to more suggestion from the people here :).

Share this post


Link to post
Share on other sites
Quote:
Original post by marshdabeachy

std::list<Tween*>::iterator iter;
for (iter = p.tweens.begin(); iter != p.tweens.end(); iter++) {
// loop through tweens using this vomit inducing code
(p.*(*iter)->setProp)( (*iter)->tweenFunct(p.GetLifeCurrent(), p.GetLifeMax(), (*iter)->elements) );
}



Is this the exact code? If so, that first line should be
std::list<Tween<T>*>::iterator iter;

Why it would produce an internal compiler error and not spew forth a mountain of real errors is beyond me though [smile]

Share this post


Link to post
Share on other sites
Quote:
p->SetTransition(&LinearInTween<unsigned>, &Sprite::SetRed, elementsR, sizeof(elementsR));
Shouldn't that be sizeof(elementsR)/sizeof(unsigned) to get the right count?

I don't have any ideas about the internal compiler error, though - sometimes they indicate bugs in your code, but sometimes just bugs in the compiler that you can't do anything about. If noone else has the answer already, it might be worth trying to compile in VS2005 or GCC, or posting a complete stripped-down example that demonstrates the problem.

Share this post


Link to post
Share on other sites
In my experience, an internal compiler error combined with template code means that your code is technically correct, but the compiler simply can't handle it. Sometimes simplifying the line causing the error can fix the problem. Try something like this:

Tween* t = *iter;
(p.*(t->setProp))( t->tweenFunct(p.GetLifeCurrent(), p.GetLifeMax(), t->elements) );

Share this post


Link to post
Share on other sites
Use source tags. And shorter lines. Not everyone gets to read code on a widescreen monitor.

Share this post


Link to post
Share on other sites
First let's make it a little less vomit-inducing. :)

Step 1: Make typedefs for the function-pointer types, and use them. Note that you don't need to name function parameters in these typedefs; function parameter *names* are never part of the function signature. Only the *types* matter.

Step 2: Make the Tween a little more intelligent by giving it an operator() which forwards to its tweenFunct. Actually, I'm going to rename that to remove the redundancy in naming.

Step 3: Reduce some of the &*&*ing syntax by making a reference inside the for-loop. Also pull out some of the loop invariants to remove focus from them.

That gives:


template <class T>
struct Tween {
typedef T (*FuncType)(float, float, std::vector<T>&);
FuncType func;
std::vector<T> elements;
typedef void (Sprite::*propertySetter)(T);
propertySetter setProp;

T operator(float life, float max) {
return func(life, max, elements);
}
};

template<class T>
void Particle::SetTransition(Tween<T>::FuncType tween, Tween<T>::propertySetter setProp, T* element, int length) {
// add tween to list
Tween* t = new Tween;
t->tweenFunct = tween;
t->setProp = setProp;
t->elements.resize(length);
for (int i=0; i<length; i++) {
t->elements = element;
}
tweens.push_back(t);
// initialize property
(this->*setProp)( (*tween)(1.0f, 1.0f, t->elements) );
}

// And the interesting code...
std::list<Tween*>::iterator iter;
float life = p.GetLifeCurrent();
float max = p.GetLifeMax();
for (iter = p.tweens.begin(); iter != p.tweens.end(); iter++) {
Tween& t = **iter; // once to get the pointer, again for a reference
(p.t->setProp)(t(life, max));
}




Now we can look at that with our heads cocked:

1) How are you supposed to make a list of 'Tween*', when Tween is a templated type? You need to fill in the 'something' in 'list-of-pointers-to-tween-of-something'.

2) WTF is 'p.t' supposed to be now? 't' is a variable, not a member name. I think you wanted just 't->setProp'.

3) Except that t isn't a pointer now; so it's just 't.setProp'.

4) Except that setProp is a pointer to a *member* function, so we need to invoke it upon an object. That would make it something like 'mySprite.*(t.setProp)'. Okay, so I guess 'p' in your case was the Sprite? Sigh. I think you were just getting a bad parse because of the operator precedence. But really, you shouldn't try to write things like that. PMFs are weird enough as it is. In fact, let's pull that work into the Tween member function too.

So now we have:


template <class T>
struct Tween {
typedef T (*FuncType)(float, float, std::vector<T>&);
FuncType func;
std::vector<T> elements;
typedef void (Sprite::*propertySetter)(T);
propertySetter setProp;

void operator(Sprite& s, float life, float max) {
// The problem with '(p.*(*iter)->setProp)' is that it tries to make
// 'p.*(*iter)' be the bound-and-ready-to-call PMF, which is already
// garbage because *iter is a Tween* rather than a PMF, and then tries to
// dereference that and get a member instead of calling.
// Now that we have the rest of the code factored, this goes more smoothly:
(s.*setProp)(func(life, max, elements));
}
};

template<class T>
void Particle::SetTransition(Tween<T>::FuncType tween, Tween<T>::propertySetter setProp, T* element, int length) {
// add tween to list
Tween* t = new Tween;
t->tweenFunct = tween;
t->setProp = setProp;
t->elements.resize(length);
for (int i=0; i<length; i++) {
t->elements = element;
}
tweens.push_back(t);
// initialize property
(*t)(*this, 1.0f, 1.0f);
}

// And the interesting code...
std::list<Tween*>::iterator iter;
float life = p.GetLifeCurrent();
float max = p.GetLifeMax();
for (iter = p.tweens.begin(); iter != p.tweens.end(); iter++) {
Tween& t = **iter; // once to get the pointer, again for a reference
t(p, life, max);
}




Finally, we figure out why there's this weird mismatch between 'Sprite' and 'Particle' types (which is part of what was throwing me off before). :) Oh, and why have that array-and-count interface? That's an ugly C throwback. Be generic and modern, and use an iterator pair (and add a constructor to the Tween):


template <class T>
struct Tween {
typedef T (*FuncType)(float, float, std::vector<T>&);
FuncType func;
std::vector<T> elements;
typedef void (Sprite::*propertySetter)(T);
propertySetter setProp;

void operator(Sprite& s, float life, float max) {
(s.*setProp)(func(life, max, elements));
}

// Constructor! And an *initializer list*! omg!
template<typename Iterator>
Tween(FuncType func, propertySetter setProp, Iterator begin, Iterator end) :
func(func), setProp(setProp), elements(begin, end) {}
};

template<class T, typename Iterator>
void Particle::SetTransition(Tween<T>::FuncType tween, Tween<T>::propertySetter setProp, Iterator begin, Iterator end) {
// Look how much shorter! Omg!
tweens.push_back(new Tween(tween, setProp, begin, end));
// initialize property
(*(tweens.back()))(*this, 1.0f, 1.0f);
}


Share this post


Link to post
Share on other sites
Thanks for the replies. I am well aware my code is not as swell as it could be, but I'm still learning and this is some of the most complicated code I've written. I've never dealt with function pointers before.

Anyway, I tried adding your code Zahlman, and received a host of errors.

Quote:

Particle.h(15) : error C2544: expected ')' for operator '()'
Particle.h(23) : see reference to class template instantiation 'Tween<T>' being compiled
Particle.h(15) : error C2146: syntax error : missing ';' before identifier 'Sprite'
Particle.h(15) : error C2182: '()' : illegal use of type 'void'
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : error C2059: syntax error : ')'
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : error C2143: syntax error : missing ';' before '{'
Particle.h(15) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
Particle.cpp
Particle.h(15) : error C2544: expected ')' for operator '()'
Particle.h(23) : see reference to class template instantiation 'Tween<T>' being compiled
Particle.h(15) : error C2146: syntax error : missing ';' before identifier 'Sprite'
Particle.h(15) : error C2182: '()' : illegal use of type 'void'
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : error C2059: syntax error : ')'
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : error C2143: syntax error : missing ';' before '{'
Particle.h(15) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
Particle.cpp(27) : warning C4346: 'Tween<T>::FuncType' : dependent name is not a type
prefix with 'typename' to indicate a type
Particle.cpp(27) : error C2146: syntax error : missing ')' before identifier 'tween'
Particle.cpp(27) : error C2182: 'SetTransition' : illegal use of type 'void'
Particle.cpp(27) : fatal error C1903: unable to recover from previous error(s); stopping compilation
Mode7.cpp
Particle.h(15) : error C2544: expected ')' for operator '()'
Particle.h(23) : see reference to class template instantiation 'Tween<T>' being compiled
Particle.h(15) : error C2146: syntax error : missing ';' before identifier 'Sprite'
Particle.h(15) : error C2182: '()' : illegal use of type 'void'
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : warning C4518: 'float ' : storage-class or type specifier(s) unexpected here; ignored
Particle.h(15) : error C2059: syntax error : ')'
Particle.h(15) : warning C4228: nonstandard extension used : qualifiers after comma in declarator list are ignored
Particle.h(15) : error C2143: syntax error : missing ';' before '{'
Particle.h(15) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
Mode7.cpp(518) : error C2955: 'Tween' : use of class template requires template argument list
Particle.h(23) : see declaration of 'Tween'
Mode7.cpp(519) : error C2064: term does not evaluate to a function taking 3 arguments


Yeah. I'd tackle these myself but this whole thing is rather confusing to me. The first error it appears to be giving is the () overload. Any thoughts?

Share this post


Link to post
Share on other sites
Typo on zahlman's part. He has


void operator(Sprite& s, float life, float max)


The proper syntax for operator() is

void operator()(Sprite& s, float life, float max)


The rest of the errors appear to be cascading errors off of that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Deyja
Typo on zahlman's part. He has


void operator(Sprite& s, float life, float max)


The proper syntax for operator() is

void operator()(Sprite& s, float life, float max)


Erm, yes. Not sure how I did that :) Well spotted.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!