Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 32,492 of 33,346    |
|    Johannes Schaub to All    |
|    Re: local function as default value    |
|    22 Jul 12 04:01:21    |
   
   From: schaub.johannes@googlemail.com   
      
   Am 20.07.2012 22:45, schrieb Daniel Krügler:   
   > 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.   
      
   > 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   
   > 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):x(defVal()) {}   
      
   One could always disallow default arguments of constructors that make   
   use of "this", though :)   
      
   > 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! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca