Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C++ reluctant to overload function

Reply
Thread Tools

C++ reluctant to overload function

 
 
Vladimir Jovic
Guest
Posts: n/a
 
      10-13-2010
Stuart Redmann wrote:
> [snipped previous discussion about issue with overloading]
>
> On 13 Okt., Öö Tiib wrote:
>> The C++ overload resolving and two-pass argument dependent lookup
>> and template argument deduction is as complex as it can only get for a
>> poor compiler.

>
> I agree that overload resolving and ADL are quite complex. However, I
> don't see why C++ should be a poor language in that regard. Or do you
> mean that most compilers are quite bad at error messages when it comes
> to errors with ADL/overload resolution? I'd value your opinion.


He probably meant that the poor compiler has to do all dirty and hard
work

Most likely he didn't mean the c++ compilers or c++ language are crap.
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      10-13-2010
On Oct 12, 5:37 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Victor Bazarov <v.baza...@comcast.invalid> wrote:
> > Name lookup when in a member function finds
> > the member 'foo' which actually *hides* any other 'foo', and that's why
> > the '<unnamed namespace>::foo' should NOT be found during that lookup
> > and is *not* considered an overload.


> What is the rationale for that? I can't immediately think of
> a reason or notivation for that.


I suspect that the main reason is that that is how name lookup
always works. In just about every language which recognizes
scope. You wouldn't want to get a duplicate definition error
because you had defined an "int foo" at namespace scope, and
having the compiler find a function name, but not the name of
a variable, would be extremely confusing.

Beyond that, of course, you really don't want the compiler
looking further than you expect. Consider for a moment:

class C
{
void f(int);
public:
void g() { f('a'); }
};

When you wrote the class, it's obvious (I suppose) that you
intended g to call C::f. And you would be most annoyed if it
called some ::f some of the time (depending on what headers were
included before this header), but not others. Similarly, if
C derived from some other class, you wouldn't like the fact that
the author of that class added a private f(char) broke your
code.

--
James Kanze
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      10-13-2010
On Oct 12, 10:40 pm, spop...@speedymail.org (Steve Pope) wrote:
> Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >On 10/12/2010 3:09 PM, Steve Pope wrote:
> >> Victor Bazarov<v.Abaza...@comAcast.net> wrote:
> >>> Rationale for what, exactly? For the rules of hiding?
> >>> Names defined in a closer scope hide names defined in the
> >>> outer scope. It's an old rule, that AFAICT existed from
> >>> the start in C++. For example,
> >>> int main()
> >>> {
> >>> double d = 3.14159;
> >>> {
> >>> int d = 42;
> >>> {
> >>> d = 666; // changes the int d, not the double d
> >>> }
> >>> }


> >>> // here 'd' is still 3.14159
> >>> }


> >> Well it's not exactly analogous. In the above case the
> >> name-mangled names clash, in the case I described in my
> >> initial post, they do not.


> >Not sure I understand what you mean here. In your example
> >the name is 'foo'. In my example the name is 'd'. Would it
> >make a difference if I named my variables 'foo'? What's
> >"name-mangled" have to do with name resolution or with name
> >hiding? And what *is* "name-mangled", anyway?


> Unless I am missing something:


> Overloaded function names do not hide each other because their
> name-mangled names include the argument types.


Overloaded function names do not hide each other because they
are in the same scope. Names in the same scope never hide one
another. A name in a given scope hides names in the enclosing
scope. The reason you can overload functions (but not
variables) is because the C++ standard allows more than one
symbol to be declared in any given scope, provided all of the
symbols are functions or function templates. (There's also
a special provision which allows the name of a class to be
declared when there is another declaration of the same name.
This is, however, a hack for C compatibility purposes, and is
best ignored.)

And there's no such thing as name mangling in C++. A variable
or a function has a name, and that's it.

> There is no such distinctoin in your variable "d" in your
> example.


> It seems in the situation in my first post, something is at
> work other than a simple need to resolve names. Some matter
> of language design philosophy that is more subtle than the
> scope of the names.


No. It's only a question of the scope of names.

--
James Kanze
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      10-13-2010
On Oct 13, 9:38*am, Stuart Redmann <DerTop...@web.de> wrote:
> [snipped previous discussion about issue with overloading]
>
> On 13 Okt., Öö Tiib wrote:
>
> > The C++ overload resolving and two-pass argument dependent lookup
> > and template argument deduction is as complex as it can only get for a
> > poor compiler.

>
> I agree that overload resolving and ADL are quite complex. However, I
> don't see why C++ should be a poor language in that regard. Or do you
> mean that most compilers are quite bad at error messages when it comes
> to errors with ADL/overload resolution? I'd value your opinion.


It was said in context of OP expectation that names should not be
hidden.

What i meant that there are already things about that name resolving
in standard that are unclear. It is apparently not only me because
different compilers (for example ICC, g++ and MSVC) also handle some
edge cases differently and it is hard to tell who is right.
Portability issues about name resolving are usually easy to repair by
qualifying the names or by renaming or by using "using" directive only
that it is sometimes hard to understand that it is again such an
issue, when templates are involved.

Example given by Victor is on one hand a good example of name hiding
feature what language allows. On other hand it is hard to see who
really needs to hide a name like that (and why). It is very hard to
believe that writer of the function did really run out of possible
names.

Several would be happy if compiler gave warning on cases when a name
hides name in a bigger scope. For example when a name in derived class
hides a name in base class. I only remember cases of major confusion
and bugs with it. OP was similarly confused when name in nameless
namespace was hidden by name in class. Unfortunately a warning about
such hiding may initially cause too numerous warnings when including
some header-only libraries ... together with some large C API
(<windows.h> for example).
 
Reply With Quote
 
Marc
Guest
Posts: n/a
 
      10-13-2010
James Kanze wrote:

> Beyond that, of course, you really don't want the compiler
> looking further than you expect. Consider for a moment:
>
> class C
> {
> void f(int);
> public:
> void g() { f('a'); }
> };
>
> When you wrote the class, it's obvious (I suppose) that you
> intended g to call C::f. And you would be most annoyed if it
> called some ::f some of the time (depending on what headers were
> included before this header), but not others. Similarly, if
> C derived from some other class, you wouldn't like the fact that
> the author of that class added a private f(char) broke your
> code.


From what I understood of the previous post, he may not have been asking
for an overload, but more like a fallback (2-phase type). That is, here
it would consider f OK and not look any further. Only when it would
otherwise give an error would it look further. That would probably be
too confusing, but at least it wouldn't break any code.
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-13-2010
Victor Bazarov <> wrote:

>On 10/12/2010 10:53 PM, Steve Pope wrote:


>> Actually, poking into this I find that one can overload functions
>> across scopes,


>But it is *not* overloading "across scopes". You're simply bringing all
>names into *the same scope*. Only then they become overloaded. If
>different scopes are involved, there can be no overloading, there is,
>however, name hiding. There is no way to marry those two actions, it's
>one or the other. If you redeclare the hidden name in the inner scope
>(so it "comes out of hiding"), then hiding doesn't apply any longer, and
>you can talk about overloading again.


>Please get your terminology straight.


I'm happy with my terminology, thanks.

> > it just must be done explicitly. So I can fix
>> the example I first gave as follows.


Steve

 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-13-2010
Vladimir Jovic <> wrote:

>Stuart Redmann wrote:


>> I agree that overload resolving and ADL are quite complex. However, I
>> don't see why C++ should be a poor language in that regard. Or do you
>> mean that most compilers are quite bad at error messages when it comes
>> to errors with ADL/overload resolution? I'd value your opinion.


>He probably meant that the poor compiler has to do all dirty and hard
>work


That is also how I interpreted it

>Most likely he didn't mean the c++ compilers or c++ language are crap.


Maintaining the separate compilation model while keeping the naming/
scoping/overloading scheme general is a balancing act.

Steve
 
Reply With Quote
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      10-13-2010
James Kanze wrote:

> On Oct 12, 10:40 pm, spop...@speedymail.org (Steve Pope) wrote:
>> Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> >On 10/12/2010 3:09 PM, Steve Pope wrote:
>> >> Victor Bazarov<v.Abaza...@comAcast.net> wrote:
>> >>> Rationale for what, exactly? For the rules of hiding?
>> >>> Names defined in a closer scope hide names defined in the
>> >>> outer scope. It's an old rule, that AFAICT existed from
>> >>> the start in C++. For example,
>> >>> int main()
>> >>> {
>> >>> double d = 3.14159;
>> >>> {
>> >>> int d = 42;
>> >>> {
>> >>> d = 666; // changes the int d, not the double d
>> >>> }
>> >>> }

>
>> >>> // here 'd' is still 3.14159
>> >>> }

>
>> >> Well it's not exactly analogous. In the above case the
>> >> name-mangled names clash, in the case I described in my
>> >> initial post, they do not.

>
>> >Not sure I understand what you mean here. In your example
>> >the name is 'foo'. In my example the name is 'd'. Would it
>> >make a difference if I named my variables 'foo'? What's
>> >"name-mangled" have to do with name resolution or with name
>> >hiding? And what *is* "name-mangled", anyway?

>
>> Unless I am missing something:

>
>> Overloaded function names do not hide each other because their
>> name-mangled names include the argument types.

>
> Overloaded function names do not hide each other because they
> are in the same scope. Names in the same scope never hide one
> another. A name in a given scope hides names in the enclosing
> scope. The reason you can overload functions (but not
> variables) is because the C++ standard allows more than one
> symbol to be declared in any given scope, provided all of the
> symbols are functions or function templates. (There's also
> a special provision which allows the name of a class to be
> declared when there is another declaration of the same name.
> This is, however, a hack for C compatibility purposes, and is
> best ignored.)
>


Since I too like to argue about things - names in the same scope can
actually hide one another.

struct A { };
void A();

Name of function hides the name of struct.

struct A {
int A;
};

Name of member hides name of struct (injected class name).
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-13-2010
Öö Tiib <> wrote:

>On Oct 13, 9:38*am, Stuart Redmann <DerTop...@web.de> wrote:


>> I agree that overload resolving and ADL are quite complex. However, I
>> don't see why C++ should be a poor language in that regard. Or do you
>> mean that most compilers are quite bad at error messages when it comes
>> to errors with ADL/overload resolution? I'd value your opinion.


>It was said in context of OP expectation that names should not be
>hidden.


Correct. Not that I expect the language to behave differently
than it is designed, just that it was not clear to me why this was a
good way to design it.

>What i meant that there are already things about that name resolving
>in standard that are unclear. It is apparently not only me because
>different compilers (for example ICC, g++ and MSVC) also handle some
>edge cases differently and it is hard to tell who is right.
>Portability issues about name resolving are usually easy to repair by
>qualifying the names or by renaming or by using "using" directive only
>that it is sometimes hard to understand that it is again such an
>issue, when templates are involved.
>
>Example given by Victor is on one hand a good example of name hiding
>feature what language allows. On other hand it is hard to see who
>really needs to hide a name like that (and why). It is very hard to
>believe that writer of the function did really run out of possible
>names.


The whole idea of overloading is to provide the programmer with
a form of polymorphism. e.g. I have a math library function

double sin(double x)

And I want to overloaded it with a vector version

vector<double> sin(vector<double> x)

Because one scope encloses the other I cannot do this without some
sort of workaround. If the nuisance factor of such workarounds inclines
the programmer to not use polymorphism when they should, then
in some sense the language design is steering them to a poor design choice.

Steve
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      10-13-2010
On 10/13/2010 11:52 AM, Johannes Schaub (litb) wrote:
> James Kanze wrote:
>
>> On Oct 12, 10:40 pm, spop...@speedymail.org (Steve Pope) wrote:
>>> Victor Bazarov<v.Abaza...@comAcast.net> wrote:
>>>> On 10/12/2010 3:09 PM, Steve Pope wrote:
>>>>> Victor Bazarov<v.Abaza...@comAcast.net> wrote:
>>>>>> Rationale for what, exactly? For the rules of hiding?
>>>>>> Names defined in a closer scope hide names defined in the
>>>>>> outer scope. It's an old rule, that AFAICT existed from
>>>>>> the start in C++. For example,
>>>>>> int main()
>>>>>> {
>>>>>> double d = 3.14159;
>>>>>> {
>>>>>> int d = 42;
>>>>>> {
>>>>>> d = 666; // changes the int d, not the double d
>>>>>> }
>>>>>> }

>>
>>>>>> // here 'd' is still 3.14159
>>>>>> }

>>
>>>>> Well it's not exactly analogous. In the above case the
>>>>> name-mangled names clash, in the case I described in my
>>>>> initial post, they do not.

>>
>>>> Not sure I understand what you mean here. In your example
>>>> the name is 'foo'. In my example the name is 'd'. Would it
>>>> make a difference if I named my variables 'foo'? What's
>>>> "name-mangled" have to do with name resolution or with name
>>>> hiding? And what *is* "name-mangled", anyway?

>>
>>> Unless I am missing something:

>>
>>> Overloaded function names do not hide each other because their
>>> name-mangled names include the argument types.

>>
>> Overloaded function names do not hide each other because they
>> are in the same scope. Names in the same scope never hide one
>> another. A name in a given scope hides names in the enclosing
>> scope. The reason you can overload functions (but not
>> variables) is because the C++ standard allows more than one
>> symbol to be declared in any given scope, provided all of the
>> symbols are functions or function templates. (There's also
>> a special provision which allows the name of a class to be
>> declared when there is another declaration of the same name.
>> This is, however, a hack for C compatibility purposes, and is
>> best ignored.)
>>

>
> Since I too like to argue about things - names in the same scope can
> actually hide one another.
>
> struct A { };
> void A();
>
> Name of function hides the name of struct.
>
> struct A {
> int A;
> };
>
> Name of member hides name of struct (injected class name).


I'd prefer to see "nitpick" to be attached to the first sentence in your
reply. Only names of classes can be hidden in the same scope. Try

struct A {
typedef int A; // not OK - two types with the same name
};

A variable can hide a class, a function can hide a class - there is a
way to force the recognition of the name as that of the class by using
the elaborate type specifier. Templates are probably the close second
since the presence of < or the keyword 'template' can bias the
compiler's interpretation (can't recall all cases right now).

But that's about it. Variables can't share names, nor can they exist
alongside functions with the same name.

Besides, we did start talking about function names, not types (see the
original post).

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: C++ reluctant to overload function James Kanze C++ 4 10-14-2010 02:12 PM
Examples of using "reluctant" subexpressions in regexps? david.karr@wamu.net Java 4 04-27-2005 07:46 PM
Help simplify complex regexp needing positive lookahead and reluctant quantifers david.karr@wamu.net Java 7 03-25-2005 09:05 PM
function overload (not operator overload) Ying-Chieh Liao Perl Misc 3 10-11-2004 11:24 AM
How use the overload of>> (or<<) of a class in the overload of << and >> of another class? Piotre Ugrumov C++ 3 01-25-2004 08:08 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57