Confused after 20 years!!

Hello!!

I'm really confused after 20 years programming in C++
I have this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
A::A()
{
	try
	{
		...

		// an exception raises here for several reasons
		throw etc...

		AString vsn;
	}
	catch (...) {}
}

As you can see, the program flow enters the try block, and sometimes an exception is thrown (the code is not complete).

Well, this causes an abnormal program termination!!!. As you know, this is frequently caused because an exception raises in a destructor. In this case, the destructor is the vsn object destructor!!! Which is not yet constructed!!!! Debugging the code I see that, when the program flow enters the try/catch block, all the local variables inside the block are constructed using indeterminated values, and therefore when the exception is raised the destructors for the local variables are invoqued, and the AString object destructor, which is in an indeterminated state, raises an exception. But "svn" shouldn't be constructed until the program flow reaches it's declaration point, as stated in ALL C++ standards and books.

So, what's happening here?
Any thoughs?
Thanks in advance!!
Last edited on
Are you sure this points to vsn when the destructor fails? That really shouldn't happen.
In addition to helios: is vsn a local variable in constructor? If that is the case, it should not be visible in any other functions, including the destructor.
What compiler are you using?

And can you repro the problem with a small, post-able program?

Andy
Thank you guys, for your interest.

Helios: Yes; Commenting the AString line everything works as expected.

Ats15: Yes, it's local, but maybe I didn't explain the problem correctly: when the exception is raised the stack starts rewinding and the local objects are destroyed; vsn shouldn't be constructed at that point, but IT IS (with an undefined status), so it gets destroyed and it's destructor throws an exception (because its undefined status). This behaviour violates all C++ standards, and therefore the program calls terminate(). But, of course, all this shouldn't happen because vsn souldn't be constructed at the "throw" line.

Andywestken: I'm using Borland C++ 2010. It's been a great compiler (so far). I'm going to build a standalone project and see what happens. If it continues failing I'll post it here.

Thanks!
Well, I've invetigated a little bit more, and this is really strange. The full constructor code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//---------------------------------------------------------------------------
AOskProject::AOskProject(const _AFullFileName& _fileName) _TH_EX :
	fileName(_fileName)
{
	try
	{
		_XML xml(fileName);
		_XMLElement& prjNode = xml[xml::xmlProject];
		_XMLElement& geNode = prjNode[xml::xmlGeneral];

		AString vsn = geNode[xml::xmlVersion].AsString();

		// etc
	}
	catch (...) {}
}


The problem raises only if the _XML object is constructed before the vsn object. Deleting all the xml stuff (and throwing something before the vsn creation) everything works well. Why does the compiler generate code to construct the vsn object when the xml object is present? I don't know. I've "solved" this by creating xml with new, but in any case I consider this behavior as a compiler bug. I cannot post a standalone project because the xml object is very complex.

Sometimes is not possible to know what's going on.
Thanks again!
Did you try another compiler? If problem does not persist, it is indeed a compiler bug. You probably should fill a bug report, so that bug could be fixed.
I will, MiiniPaa, thanks. I'll also try in another compiler.
Last edited on
Topic archived. No new replies allowed.