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
} 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/
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.
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/ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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
|
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...
|
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...
|
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
{
|
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.
| |
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...
|
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.)
|
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
|
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 ;
|
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...
|
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...
| |
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...
|
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,...
|
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();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
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...
| |