Confused after 20 years!!

May 27, 2013 at 12:11am
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 May 27, 2013 at 12:12am
May 27, 2013 at 12:49am
Are you sure this points to vsn when the destructor fails? That really shouldn't happen.
May 27, 2013 at 1:54am
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.
May 27, 2013 at 3:12am
What compiler are you using?

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

Andy
May 27, 2013 at 7:28am
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!
May 27, 2013 at 7:55am
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!
May 27, 2013 at 10:44am
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.
May 27, 2013 at 11:29am
I will, MiiniPaa, thanks. I'll also try in another compiler.
Last edited on May 27, 2013 at 12:33pm
Topic archived. No new replies allowed.