Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   C++ reluctant to overload function (http://www.velocityreviews.com/forums/t735293-c-reluctant-to-overload-function.html)

Steve Pope 10-12-2010 02:14 PM

C++ reluctant to overload function
 
A very simple question follows.

Is it correct operation that the following fails to compile if
I uncomment the line indicated, and if so, what rule precludes
overloading the function foo() in the manner I am attempting
(based on type/number of operators)?

It seems unambiguous to me.

Thanks

Steve

*************************************


#include <cstdio>

struct a {

// uncommenting the following line causes it to fail to compile
// void foo(int x) { std::printf("%d\n", 2*x); }

void do_foo();
};

namespace {
void foo(int x, int y) {std::printf("%d\n", x + y); }
}

void a::do_foo() {
foo(2,4);
}

main() {
a y;
y.do_foo();
}



Victor Bazarov 10-12-2010 02:24 PM

Re: C++ reluctant to overload function
 
On 10/12/2010 10:14 AM, Steve Pope wrote:
> A very simple question follows.
>
> Is it correct operation that the following fails to compile if
> I uncomment the line indicated, and if so, what rule precludes
> overloading the function foo() in the manner I am attempting
> (based on type/number of operators)?
>
> It seems unambiguous to me.
>
> Thanks
>
> Steve
>
> *************************************
>
>
> #include<cstdio>
>
> struct a {
>
> // uncommenting the following line causes it to fail to compile
> // void foo(int x) { std::printf("%d\n", 2*x); }
>
> void do_foo();
> };
>
> namespace {
> void foo(int x, int y) {std::printf("%d\n", x + y); }
> }
>
> void a::do_foo() {
> foo(2,4);
> }
>
> main() {


int main() { // there is no implicit int in C++

> a y;
> y.do_foo();
> }


The program with uncommented 'foo' member should fail to compile - too
many arguments for a::foo. 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 compiler finds the non-member 'foo' if you uncomment 'a::foo'?

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

Steve Pope 10-12-2010 02:24 PM

Re: C++ reluctant to overload function
 
Pete Becker <pete@versatilecoding.com> wrote:

>On 2010-10-12 10:14:20 -0400, Steve Pope said:


>> A very simple question follows.


>> Is it correct operation that the following fails to compile if
>> I uncomment the line indicated, and if so, what rule precludes
>> overloading the function foo() in the manner I am attempting
>> (based on type/number of operators)?


>Overloading only applies to names that are defined in the same scope.
>Here, the first version of foo is defined as a member of struct a and
>the second version of foo is defined in the anonymous namespace. Two
>different scopes, so no overloading.


That does appear to be going on. Thanks.

Not sure it's a reasonable restriction though. Not that this
opinion counts for anything ;-)

Steve

Steve Pope 10-12-2010 02:42 PM

Re: C++ reluctant to overload function
 
Victor Bazarov <v.bazarov@comcast.invalid> wrote:

>On 10/12/2010 10:14 AM, Steve Pope wrote:


>> main() {

>
>int main() { // there is no implicit int in C++


Thanks

>The program with uncommented 'foo' member should fail to compile - too
>many arguments for a::foo. 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 compiler finds the non-member 'foo' if you uncomment 'a::foo'?


None. It just seemed to me that, given the wild abandon with
which the linker will usually search for a function that matches
the prototype, I'm a bit surprised it doesn't find and use this one.


Steve

Juha Nieminen 10-12-2010 04:37 PM

Re: C++ reluctant to overload function
 
Victor Bazarov <v.bazarov@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.

Steve Pope 10-12-2010 07:09 PM

Re: C++ reluctant to overload function
 
Victor Bazarov <v.Abazarov@comAcast.net> wrote:

>On 10/12/2010 12:37 PM, Juha Nieminen wrote:


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


>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.

Steve

Steve Pope 10-12-2010 09:40 PM

Re: C++ reluctant to overload function
 
Victor Bazarov <v.Abazarov@comAcast.net> wrote:

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


>> Victor Bazarov<v.Abazarov@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.

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.


Steve

Öö Tiib 10-12-2010 10:21 PM

Re: C++ reluctant to overload function
 
On 13 okt, 00:40, 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.


Yes you miss. It is not linker who does resolve names. It is in
another way around. Linker is stupid. Compiler is smart. Nothing of it
is specified by language rules, it is just done that way by most
implementations.

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


The d-s of Victor are of different type and if these had external
linkage then compiler had to name-mangle them differently to make
difference for linker.

> 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. 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. If it had to mix all the names from all the scopes
available without hiding the names in outer scope then that would
cause huge amount of ambiguities (compiler just fails to resolve) in
already existing code.

Steve Pope 10-13-2010 02:53 AM

Re: C++ reluctant to overload function
 
Victor Bazarov <v.Abazarov@comAcast.net> wrote:

>When *hiding* takes place, overloading is not present. That's what I
>think you're missing. You can only overload functions in the same
>scope. As soon as there is the same name declared in a more enclosed
>scope, it *hides* the name from the outer scope. No overloading in that
>case. None. Zero. Zilch. Nada.


Actually, poking into this I find that one can overload functions
across scopes, it just must be done explicitly. So I can fix
the example I first gave as follows.

Steve

*****************************


#include <cstdio>

struct a {

// uncommenting the following line no longer
// causes it to fail to compile

void foo(int x) { std::printf("%d\n", 2*x); }

void do_foo();
};

namespace {
void foo(int x, int y) {std::printf("%d\n", x + y); }
}

void a::do_foo() {
using ::foo; // because of this line
foo(2,4);
}

main() {
a y;
y.do_foo();
}



Stuart Redmann 10-13-2010 06:38 AM

Re: C++ reluctant to overload function
 
[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.

Regards,
Stuart


All times are GMT. The time now is 03:28 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.