C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

local function as default value

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Ivan Godard
Guest





PostPosted: Fri Jul 20, 2012 6:44 pm    Post subject: local function as default value Reply with quote



The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to be
called there must be an "S" value to be "this" at the call site, which
could be used as "this" for "defVal" too. Presumably the same would
apply to a local data member used as a default as well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Andy Champ
Guest





PostPosted: Fri Jul 20, 2012 8:43 pm    Post subject: Re: local function as default value Reply with quote



On 20/07/2012 19:44, Ivan Godard wrote:
Quote:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to
be called there must be an "S" value to be "this" at the call site,
which could be used as "this" for "defVal" too. Presumably the same
would apply to a local data member used as a default as well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?

At the time defVal() gets called you don't have an S to connect it to
- what would be the value of "this" within the defVal function?

(In the second case defVal gets called from within the second p(...)
function and uses its "this")

You could also get around it by making defVal static, so it doesn't
have a "this".

Andy


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Daniel Krügler
Guest





PostPosted: Fri Jul 20, 2012 8:45 pm    Post subject: Re: local function as default value Reply with quote



Am 20.07.2012 20:44, schrieb Ivan Godard:
Quote:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to
be called there must be an "S" value to be "this" at the call site,
which could be used as "this" for "defVal" too. Presumably the same
would apply to a local data member used as a default as well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?

IMO the current restrictions make sense. Keep in mind that default
arguments are simply expressions that will be used instead of the
actual function call. Now consider the call expression

s.p(0)

for some object s. This has the same semantics like

s.p(0, defval())

but there is no free function defval in sight, so the compiler is
right to reject you code upfront.

You argument that the compiler could use the object expression that is
used to invoke function p should be considered cautiously. IMO it much
more complicates the mental model of the translation of the call by
the compiler. The situation would also become more complicated, if we
consider default arguments of a constructor

struct S {
int defVal() { return 0; }
S(int i, int j = defVal()) {}
};

Would you really want that the compiler translates this to executable
code?

I don't think that your suggested language extension would solve more
problems than it introduces.

HTH & Greetings from Bremen,

- Daniel Krügler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ivan Godard
Guest





PostPosted: Sat Jul 21, 2012 12:42 am    Post subject: Re: local function as default value Reply with quote

On 7/20/2012 1:43 PM, Andy Champ wrote:
Quote:
On 20/07/2012 19:44, Ivan Godard wrote:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to
be called there must be an "S" value to be "this" at the call site,
which could be used as "this" for "defVal" too. Presumably the same
would apply to a local data member used as a default as well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?

At the time defVal() gets called you don't have an S to connect it to
- what would be the value of "this" within the defVal function?

(In the second case defVal gets called from within the second p(...)
function and uses its "this")

You could also get around it by making defVal static, so it doesn't
have a "this".

Andy


Yes, I know that's the way it's defined - but why is it defined that

way? The compiler knows perfectly well what "this" it will use to call
p, and could use that to call defVal, in effect performing my manual
expansion without requiring me to write the second function. There
should not be any implementation issues involved in making the default
arguments evaluate in what is in effect the scope of the function body.

Is there a practical problem with this that I've overlooked, or is it
just happenstance and nobody had thought of it?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Gerhard Fiedler
Guest





PostPosted: Sat Jul 21, 2012 2:41 pm    Post subject: Re: local function as default value Reply with quote

On 2012-07-20 21:42:05, in comp.lang.c++.moderated Ivan Godard wrote:

Quote:
On 7/20/2012 1:43 PM, Andy Champ wrote:
On 20/07/2012 19:44, Ivan Godard wrote:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to
be called there must be an "S" value to be "this" at the call
site, which could be used as "this" for "defVal" too. Presumably
the same would apply to a local data member used as a default as
well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?

At the time defVal() gets called you don't have an S to connect it
to - what would be the value of "this" within the defVal function?

(In the second case defVal gets called from within the second
p(...) function and uses its "this")

You could also get around it by making defVal static, so it doesn't
have a "this".

Andy


Yes, I know that's the way it's defined - but why is it defined that
way? The compiler knows perfectly well what "this" it will use to
call p, and could use that to call defVal, in effect performing my
manual expansion without requiring me to write the second
function. There should not be any implementation issues involved in
making the default arguments evaluate in what is in effect the scope
of the function body.

Is there a practical problem with this that I've overlooked, or is
it just happenstance and nobody had thought of it?

At the time defVal() is called (before the code enters the ctor),
there is no "this". AIUI, "this" only starts to exist in a meaningful
way after all base classes and members have been initialized, and
that's way later than the call to the ctor. I think there is a
sequence point before entering the ctor at which point the arguments
must have been evaluated, and there is no way to evaluate the
non-static defVal() before even entering the ctor.

Your manual expansion is something completely different. It may end up
having the same effect in some specific cases, but it definitely is
not the same.

That's also why using a static function works: it doesn't need a
constructed object.

Gerhard


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Johannes Schaub
Guest





PostPosted: Sun Jul 22, 2012 11:01 am    Post subject: Re: local function as default value Reply with quote

Am 20.07.2012 20:44, schrieb Ivan Godard:
Quote:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to be
called there must be an "S" value to be "this" at the call site, which
could be used as "this" for "defVal" too. Presumably the same would
apply to a local data member used as a default as well.


Sounds good to me, but I may be missing some problem this would cause.
Note that default arguments are late-parsed (their state of "S" is the
one that S has at the closing "};"), so it knows whether "p" is a const
or non-const member function when parsing the default argument and can
hence correctly overload-resolve the function name.

What would be left is making "this" visible during the declaration of
parameters or, which would also work here, during the parsing of default
arguments. But I cannot see any problem here either.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Johannes Schaub
Guest





PostPosted: Sun Jul 22, 2012 11:01 am    Post subject: Re: local function as default value Reply with quote

Am 20.07.2012 22:45, schrieb Daniel Krügler:
Quote:
Am 20.07.2012 20:44, schrieb Ivan Godard:
The following seems reasonable:
struct S {
int defVal() { return 0; }
void p(int i, int j = defVal()) {}
};
but gets:
error: a nonstatic member reference must be relative to a
specific object
void p(int i, int j = defVal()) {}
and similar on other compilers. This seems odd to me: if "p" is to
be called there must be an "S" value to be "this" at the call site,
which could be used as "this" for "defVal" too. Presumably the same
would apply to a local data member used as a default as well.

Yes, I know there's an easy workaround:
struct S {
int defVal() { return 0; }
void p(int i, int j) {}
void p(int i) { p(defVal()); }
};
but why is it necessary?

IMO the current restrictions make sense. Keep in mind that default
arguments are simply expressions that will be used instead of the
actual function call. Now consider the call expression

s.p(0)

for some object s. This has the same semantics like

s.p(0, defval())

but there is no free function defval in sight, so the compiler is
right to reject you code upfront.


Hmm, but binding is done at the point of parsing of the default
argument. Consider

namespace A {
int x;
void f(int a, int b = x);
}

int main() {
A::f(0);
}

If it would be simply putting the expression into the function call and
then parse it, this would fail too.

Note that in the default argument of the original poster, if "this" can
be used in the default argument, the "implicit this transformation"
would make "defVal" into "(*this).defVal". So the binding would
correctly refer to the object expression by use of the implicit object
parameter.

Quote:
You argument that the compiler could use the object expression that is
used to invoke function p should be considered cautiously. IMO it much
more complicates the mental model of the translation of the call by
the compiler.


I think it would require the compiler to first initialize the implicit
object parameter reference with the object expression before evaluating
default arguments that make use of "this".

Unfortunately I don't know how much that complicates existing
implementations.


The situation would also become more complicated, if we
Quote:
consider default arguments of a constructor

struct S {
int defVal() { return 0; }
S(int i, int j = defVal()) {}
};

Would you really want that the compiler translates this to executable
code?


I think this code is no worse than

S(int i, int j)Mad(defVal()) {}

One could always disallow default arguments of constructors that make
use of "this", though :)

Quote:
I don't think that your suggested language extension would solve more
problems than it introduces.


I personally think that it's a surprise that this is not allowed.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Francis Glassborow
Guest





PostPosted: Sun Jul 22, 2012 12:58 pm    Post subject: Re: local function as default value Reply with quote

{ Please provide one or more small quotes to establish context -mod }

One reason that I pushed hard for forwarding ctors was that it reduced
the need for default values as, IIUC, in respect to default function
parameters they can always be replaced by overloading. Is there a use
case where default parameter values is necessary and/or makes code
essentially more readable and maintainable?

I think that class template value parameters may be different issue.

Francis


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
 


Powered by phpBB © 2001, 2006 phpBB Group