473,811 Members | 2,557 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this code supposed to throw or not ?


This is one of those, hugh ? moments.

So, GCC behaves just like I would kinda expect it to but it looks VERY
strange.

It's one of those things that could cause silent strife if you included
files in the wrong order.
class X;

extern X a;
extern X b;

// class X is incomplete ... right ?

inline bool IsEqual( X & i, X & j )
{
// using operator & () on an incomplete class ... OK
// OK we know what this is supposed to do ... right ?
return (&i) == (&j);
}

class X
{
public:
// BUT WAIT
// Place a definition for operator & in the class.
// - basically throw allways.
X * operator & () { throw "Yikes"; };
};

inline bool IsEqualOverride ( X & i, X & j )
{
// using operator & () - should use the one defined in the cloass
//
return (&i) == (&j);
}

int main()
{
X x;

// should this throw ?
IsEqual( x, x ); // datapoint - GCC does not throw

// this should throw ... right ?
IsEqualOverride (( x, x ); // GCC throws here
}

Jul 19 '05 #1
3 1472
Gianni Mariani wrote in news:bj******** @dispatch.conce ntric.net:

This is one of those, hugh ? moments.

So, GCC behaves just like I would kinda expect it to but it looks VERY
strange.

It's one of those things that could cause silent strife if you included
files in the wrong order.
<£0.02>
Nope, its if you abuse the ability to declare incomplete types.
</£0.02>

class X;

extern X a;
extern X b;

// class X is incomplete ... right ?

inline bool IsEqual( X & i, X & j )
{
// using operator & () on an incomplete class ... OK
// OK we know what this is supposed to do ... right ?
return (&i) == (&j);
I suppose here the compiler should build an overload set for
op & and A) select the right one or B) not find any and use
the comiler generated op &.

gcc does (B). We can't complain, Its done what we asked it too!
}

class X
{
public:
// BUT WAIT
// Place a definition for operator & in the class.
// - basically throw allways.
X * operator & () { throw "Yikes"; };
};
You could replace the above with:

X * operator & ( X & ) { throw "Yikes"; };

inline bool IsEqualOverride ( X & i, X & j )
{
// using operator & () - should use the one defined in the cloass
//
Does the same again, this time uses (A).
return (&i) == (&j);
}

class X {}; // to go with the non-member op & above.
int main()
{
X x;

// should this throw ?
Absolutely *NOT* ( was that loud enough :) ), if it did the compiler
would be doing something we didn't ask it to.
IsEqual( x, x ); // datapoint - GCC does not throw

// this should throw ... right ?
Once we remove the extra '(', it should, again its what we asked for.
IsEqualOverride (( x, x ); // GCC throws here
}


Note that the include order problem goes away if we 1) include
a complete declaration for X with member op &, or 2) provide a
declaration ( and optionaly a definition ) for a non-member op &.
Just add a bit more confusion to the mix, if you put
template < typename X > before the declaration of IsEqual() all
3 (*) compilers I checked threw, even when X was complete before
and op & was declared after, defered ADL I belive, though it
could be that templates are fancy macro's :).

(*) msvc 7.1 /Za, gcc 3.2 and bcc32.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #2
Rob Williscroft wrote:
Gianni Mariani wrote in news:bj******** @dispatch.conce ntric.net: .... <?0.02>
Nope, its if you abuse the ability to declare incomplete types.
</?0.02>
Incomplete types are a convenient way to separate a hairy implementation
from the rest of the application. I've used this to separate a state
machine and an application. In the state machine implementation, a
state was allowed to be part of an expression. In the rest of the
application it was used as an indicator of the current state and the
only interesting operator was is equal. There were other incomplete
types e.g properties that were used to communicate values between app
and state machine. The expression system was big and potentially
misleading for the application and separating state machine and
application code forced application programmers to structure their code
better.

I overlooked the unary & operator implications. (Not that it was used
in the state machine) - just that it's the only operator that may me
used on an incomplete class - but may be overridden once the class is
defined.

It should be one of those big red flahing warnings when overloading
unary operator &.


Absolutely *NOT* ( was that loud enough :) ), if it did the compiler
would be doing something we didn't ask it to.
But a template would/might not ... right ?

IsEqual( x, x ); // datapoint - GCC does not throw

// this should throw ... right ?

Once we remove the extra '(', it should, again its what we asked for.

IsEqualOverride (( x, x ); // GCC throws here
}

Note that the include order problem goes away if we 1) include
a complete declaration for X with member op &, or 2) provide a
declaration ( and optionaly a definition ) for a non-member op &.


I can think of few things in C++ where within a single scope, behaviour
of a function may change depending on where it is defined.

Just add a bit more confusion to the mix, if you put
template < typename X > before the declaration of IsEqual() all
3 (*) compilers I checked threw, even when X was complete before
and op & was declared after, defered ADL I belive, though it
could be that templates are fancy macro's :).


This is one more example whereby even though we use a template depending
on where it is first instantiated, it will either throw or not.

template <typename T>
inline bool Tequal( T & i, T & j )
{
return (&i) == (&j);
}

class X;

bool func( X & i, X & j )
{
return Tequal( i, j );
}

extern X a;
extern X b;

inline bool IsEqual( X & i, X & j )
{
return (&i) == (&j);
}

class X
{
public:
X * operator & () { throw "Yikes"; };

};

inline bool IsEqualOverride ( X & i, X & j )
{
return (&i) == (&j);
}
int main()
{
X x;

func( x, x );
Tequal( x, x );

// IsEqual( x, x );

// IsEqualOverride ( x, x );
}

I'm starting to think this is a language defect.

Jul 19 '05 #3
Gianni Mariani wrote in news:bj******** @dispatch.conce ntric.net:
Rob Williscroft wrote:
Gianni Mariani wrote in news:bj******** @dispatch.conce ntric.net: ...
<?0.02>
Nope, its if you abuse the ability to declare incomplete types.
</?0.02>


Incomplete types are a convenient way to separate a hairy implementation
from the rest of the application. I've used this to separate a state
machine and an application. In the state machine implementation, a
state was allowed to be part of an expression. In the rest of the
application it was used as an indicator of the current state and the
only interesting operator was is equal. There were other incomplete
types e.g properties that were used to communicate values between app
and state machine. The expression system was big and potentially
misleading for the application and separating state machine and
application code forced application programmers to structure their code
better.

I overlooked the unary & operator implications. (Not that it was used
in the state machine) - just that it's the only operator that may me
used on an incomplete class - but may be overridden once the class is
defined.

It should be one of those big red flahing warnings when overloading
unary operator &.


Well It really applies to all operator's and overloadable function's
that take references or pointers.

Absolutely *NOT* ( was that loud enough :) ), if it did the compiler
would be doing something we didn't ask it to.


But a template would/might not ... right ?


A template should use ADL (koenig lookup) at the point of instantiation
(as I understand it), so It should. My smart-ass remark about templates
being macro's was aluding to the fact many compilers will get this
right, even though they arn't doing the right thing.

[snip]

Note that the include order problem goes away if we 1) include
a complete declaration for X with member op &, or 2) provide a
declaration ( and optionaly a definition ) for a non-member op &.


I can think of few things in C++ where within a single scope, behaviour
of a function may change depending on where it is defined.


Overload resolution changes it all the time.

int f( double );
int example() { return f( 0 ); }
int f( int ); // move this up a line and the programme changes.

Just add a bit more confusion to the mix, if you put
template < typename X > before the declaration of IsEqual() all
3 (*) compilers I checked threw, even when X was complete before
and op & was declared after, defered ADL I belive, though it
could be that templates are fancy macro's :).

This is one more example whereby even though we use a template depending
on where it is first instantiated, it will either throw or not.


template <typename T>
inline bool Tequal( T & i, T & j )
{
return (&i) == (&j);
}

class X;

bool func( X & i, X & j )
{
return Tequal( i, j );
}

extern X a;
extern X b;

inline bool IsEqual( X & i, X & j )
{
return (&i) == (&j);
}

class X
{
public:
X * operator & () { throw "Yikes"; };

};

inline bool IsEqualOverride ( X & i, X & j )
{
return (&i) == (&j);
}
[snip - main()]

I'm starting to think this is a language defect.


I changed main() thus:

#define Try( x ) { \
std::cout << #x "\t"; \
try {{x} std::cout << "OK"; } catch (char const *s) { std::cout << s; } \
std::cout << std::endl; }\

int main()
{
X x;
Try( func( x, x ); )
Try( Tequal( x, x ); )
Try( IsEqual( x, x ); )
Try( IsEqualOverride ( x, x ); )
}

msvc 7.1 /Za:
func( x, x ); Yikes
Tequal( x, x ); Yikes
IsEqual( x, x ); OK
IsEqualOverride ( x, x ); Yikes

gcc 3.2 (g++):
func( x, x ); OK
Tequal( x, x ); OK
IsEqual( x, x ); OK
IsEqualOverride ( x, x ); Yikes

bcc32:
func( x, x ); OK
Tequal( x, x ); Yikes
IsEqual( x, x ); Yikes
IsEqualOverride ( x, x ); Yikes
My reading would be that results should be OK, Yikes, OK, Yikes.
But this is impossible, as it means having 2 version's of Tequal<X>.

I think you're right about there being a defect in here. The question
is - what's the defect and what's the fix:

1) Have all overload resolution done by the linker - all output Yikes.
this hasn't got any legs, it just wouldn't be C++ anymore!
Breaks mode code than you can shake a stick at.

2) Stop ADL-at-point-of-instantiation adding to the overload set.
Output as gcc. But it breaks a whole bunch of existing template
code, some in namesace std!

3) Stop ADL-at-point-of-instantiation adding to the overload set if
and only if there is one or more (possibly compiler generated)
overloads available. Output as gcc again. Breaks less code than
(2), possibly some in namespace std.

I'd actually favour (2) as specialization does IMO a much cleaner
job than ADL-at-point-of-instantiation, particularly if we get
partial function specialization (*) as well.

(*) This is being considerd I belive.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

242
13474
by: James Cameron | last post by:
Hi I'm developing a program and the client is worried about future reuse of the code. Say 5, 10, 15 years down the road. This will be a major factor in selecting the development language. Any comments on past experience, research articles, comments on the matter would be much appreciated. I suspect something like C would be the best based on comments I received from the VB news group. Thanks for the help in advance James Cameron
3
1717
by: Eric Hudson | last post by:
A quick rant and a question. Why does the designer in VS2003 delete code about custom components that it can't load? I've had large sections of forms disappear in the blink of an eye just because I've introduced a small error in a widely used custom control that makes it throw an exception at design time. IMHO the code should be sacrosanct -- if the designer can't create some sub control then it should just throw up a blank or a red X...
16
7958
by: Esteban404 | last post by:
I have a Winform news kiosk app which connects to a SQL database. When the main form is running, it reaches a threshold time or number of sequential operations and then loads another instance with a different dataset. The datasets are based on local settings which I'm determining from IP space (all machines running in that space will show the same news). The "special" set is constructed at runtime so all important messages play in their...
6
1497
by: C# Learner | last post by:
In the following two code blocks, DoSomethingUseful throws AnException, while neither of the other called methods throw any exceptions. Which of the code blocks is better (in terms of readability, maintainability, etc.), in your opinions? A { Start(); try {
1
4460
by: Egbert Nierop \(MVP for IIS\) | last post by:
Hi, I'm 'improving' CComBSTR (yes, I do still program unmanaged code in addition to C# ) to contain features, not found in it. Does anybody have good code which maches LastIndexOf()? If this is ready, I will publish the full CComBSTR class on my weblog.
171
7827
by: tshad | last post by:
I am just trying to decide whether to split my code and uses code behind. I did it with one of my pages and found it was quite a bit of trouble. I know that most people (and books and articles) like it because you can split the code from the design. That is logical. But if you are the only one working on the code, it seem a little overkill. I use Dreamweaver to do my design and find it a bit of a hassle to have multiple files open...
21
1801
by: Jim | last post by:
I am trying to write an HTTP/HTTPS proxy server in VB.Net 2005. But, I don't really even know how the internal workings of a proxy should act. Does anyone have anything on the protocols used in handling requests by proxies? I have Googled my eyes out....and found nothing. (BTW, props to Google for refusing the ridiculous request for their search results.)
3
2951
by: josh.kuo | last post by:
Sorry about the subject, I can't think of a better one. I recently wrote some PHP classes that I think might be of interest to this group. Since I have been reaping the benefits of reading news groups for years, I figure it's time for me to contribute a little bit back, maybe some people out there will find this useful. * Introduction This is a "how-to" style article, showing by example how to dynamically
27
2971
by: George2 | last post by:
Hello everyone, Should I delete memory pointed by pointer a if there is bad_alloc when allocating memory in memory pointed by pointer b? I am not sure whether there will be memory leak if I do not delete a. try { a = new int ;
0
9730
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10651
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10392
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10403
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6893
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5555
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5693
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4341
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3020
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.