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

different result in gcc & icc in throwing exceptions

Milind_Kulkarni__Int
New Contributor II
425 Views
Hi,

I have following code which gives different output for g++ and icc across all versions of the compilers in Linux*.

//////////////////////////////////////
[bash]#include 

using namespace std;

int getInt(int i) throw(int) {
	throw i;
	return i;
}

int main() {
	try {
		try {
			cout << getInt(10) << " " << getInt(20) << endl;
		}
		catch(int f) {
			cout << "int: " << f << endl;
			throw;
		}
		
	}
	catch(int i) {
		cout << "outer int: " << i << endl;
	}
	

	return 0;
}
[/bash]
/////////////////////////////////

With g++ any version:-- output is

./a.out

int: 20

outer int: 20

With icc any version, output is:--

./a.out

int: 10

outer int: 10

Is that the icc seems to work right.

What is the reason for this difference in results.

0 Kudos
7 Replies
Milind_Kulkarni__Int
New Contributor II
425 Views
When I use:--

int getInt(int i) throw()

instead of

int getInt(int i) throw(int)

I get this following error for both g++ and icc/icpc

./a.out

terminate called after throwing an instance of 'int'

Aborted

But the throw() syntax should also work. Please correct me if wrong.

Thanks

0 Kudos
Judith_W_Intel
Employee
425 Views
To answer the last question the throw() specification syntax means this function should not throw anything. So terminate is called when any throw occurs, no matter what the type.
0 Kudos
Milind_Kulkarni__Int
New Contributor II
425 Views

Hi Judy,

The same throw() syntax works correctly in Windows* systems for icl and Microsoft* compilers , and also the runtime output also seems to be the same for both.

Then why does throw() syntax not work in Linux*.

Thanks

0 Kudos
Judith_W_Intel
Employee
425 Views
It is actually working correctly on Linux andincorrectly on Windows, because the Microsoft compiler allows one to specify throw specifications but omits the standard-mandate runtime behaviorif you violate them.

Judy
0 Kudos
Milind_Kulkarni__Int
New Contributor II
425 Views

Okay thanks got it. I will have to throw differently in Linux* & Windows* , applying slightly different syntax, and it will work.

My only more question that is unanswered is:--

I get different result in icc vs g++ (across all versions).

In the former, I get 10, in the latter I get 20. What can be the logic for this.
Which is the correct result.

Thanks

0 Kudos
Judith_W_Intel
Employee
425 Views

According to the standard the behaviour is undefined here (and if you promote the remark to warning by using the -ww981 option you'll see our compiler gives a diagnostic):

t.cpp(11): warning #981: operands are evaluated in unspecified order
printf("%d %d\n",getInt(10),getInt(20));

But I think we should try to match the behaviour of Gnu in our Linux compiler.

A possible workaround for now is to use the -rev_arg_eval option which reverse the order of evaluation of the arguments so getInt(20) is evaluated first.

Judy
0 Kudos
kfsone
New Contributor I
425 Views
I interviewed for Yahoo! in 2004, and they used this as an interview question :) I thought it was defined, but the behavior is undefined because of the way arguments are passed under different environments/calling conventions :)
For instance - if the values are being passed via the stack, they may be loaded backwards, whereas if they are being passed in registers, they may be loaded in the written order.
0 Kudos
Reply