function default arguments from other arguments

Discussion in 'C++' started by tutmann, Oct 17, 2006.

  1. tutmann

    tutmann Guest

    Hello,

    to make it short, why does this not compile?

    class B {
    public:
    int b(void) { return 1;}
    }
    void f( B x, int i = x.b()) { }

    in gcc 3.3 I get error: 'x' was not declared in this scope

    But...I just declared x before. Why can't I use it?

    Henning
    tutmann, Oct 17, 2006
    #1
    1. Advertising

  2. * tutmann:
    > Hello,
    >
    > to make it short, why does this not compile?
    >
    > class B {
    > public:
    > int b(void) { return 1;}
    > }
    > void f( B x, int i = x.b()) { }
    >
    > in gcc 3.3 I get error: 'x' was not declared in this scope
    >
    > But...I just declared x before. Why can't I use it?


    You mean, why does the language forbid that?

    Presumably to simplify things for the compilerm, but ask in [comp.std.c++].

    Simple workaround is to overload f.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 17, 2006
    #2
    1. Advertising

  3. tutmann

    Bart Guest

    tutmann wrote:
    > Hello,
    >
    > to make it short, why does this not compile?
    >
    > class B {
    > public:
    > int b(void) { return 1;}
    > }
    > void f( B x, int i = x.b()) { }
    >
    > in gcc 3.3 I get error: 'x' was not declared in this scope
    >
    > But...I just declared x before. Why can't I use it?


    GGG's message is extremely misleading actually. x is already declared
    at that point (and hides any other 'x' that may have been declared
    before), but cannot be used in a default argument expression. The
    reason is that the order of evaluation of function arguments is
    unspecified.

    An obvious workaround is a one-argument overload that calls the
    two-argument function.

    Regards,
    Bart.
    Bart, Oct 17, 2006
    #3
  4. tutmann

    Salt_Peter Guest

    tutmann wrote:
    > Hello,
    >
    > to make it short, why does this not compile?
    >
    > class B {
    > public:
    > int b(void) { return 1;}
    > }


    semicolon required - B is a class declaration (and definition here)
    Also, int b() is attempting to return a literal - a const integer so...

    class B
    {
    public:
    int b() const { return 1; }
    }; // <- semicolon

    > void f( B x, int i = x.b()) { }


    the first x is an instance of B, the second x does not exist, your
    compiler might accept the function if you reverse the parameters but
    its still a bad idea and officially undefined behaviour. Isn't the goal
    to pass an instance of B into the function enough? Why would you need
    to add an uneccessary integer parameter?

    #include <iostream>

    class B
    {
    public:
    int b() const { return 1; }
    };

    void f(B x)
    {
    int i = x.b(); // i needs not be in the parameter list
    std::cout << "i = " << i << std::endl;
    }

    int main()
    {
    B b;
    f(b);

    return 0;
    }

    /* output:
    i = 1
    */

    >
    > in gcc 3.3 I get error: 'x' was not declared in this scope
    >
    > But...I just declared x before. Why can't I use it?


    because gcc happens to process the parameters from right to left. So
    that x is undeclared. Note that the sequence with which the parameters
    gets processed doesn't matter. A Parameter should never, ever be a
    dependant of another parameter.

    You could have written something like:
    void f( B x, int i = B z.b()) { }
    but even that defies any logic here.

    Maybe if you wrote class B differently you might understand when more
    than one parameter makes sense.

    #include <iostream>

    class B
    {
    int b; // private member
    public:
    B(int n) : b(n) { } // ctor
    int get() const { return b; } // accessor
    };

    void bar( B xval, B yval = B(22) ) // 2 seperate values or instances
    { // one default
    param provided via ctor + copy
    std::cout << "\nx = " << xval.get() << std::endl;
    std::cout << "y = " << yval.get() << std::endl;
    int i = yval.get();
    std::cout << "i = " << i << std::endl;
    }

    int main()
    {
    B x(4);
    B y(9);
    bar(x, y); // pass by value
    bar(x); // yval is default initialized

    return 0;
    }

    /*
    x = 4
    y = 9
    i = 9

    x = 4
    y = 22
    i = 22
    */

    Consider getting a book like this one http://www.acceleratedcpp.com
    There is enough material there to last you a lifetime.
    Salt_Peter, Oct 17, 2006
    #4
  5. tutmann

    Bart Guest

    Salt_Peter wrote:
    > tutmann wrote:
    > > void f( B x, int i = x.b()) { }

    >
    > the first x is an instance of B, the second x does not exist, your
    > compiler might accept the function if you reverse the parameters but
    > its still a bad idea and officially undefined behaviour.


    That is incorrect. According to official C++ rules, parameters declared
    before the default argument expression are in scope. The **order of
    evaluation** is unspecified, but it has nothing to do with scoping
    rules.

    > > in gcc 3.3 I get error: 'x' was not declared in this scope
    > >
    > > But...I just declared x before. Why can't I use it?

    >
    > because gcc happens to process the parameters from right to left.


    That is not the reason for the error. GCC is right to give an error,
    but the error message is a lie.

    Regards,
    Bart.
    Bart, Oct 17, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ajax Chelsea
    Replies:
    1
    Views:
    423
    Ron Natalie
    Dec 2, 2003
  2. komal
    Replies:
    6
    Views:
    1,406
    msalters
    Jan 25, 2005
  3. Edward Diener
    Replies:
    14
    Views:
    4,885
    Josiah Carlson
    Apr 6, 2004
  4. Eric Lilja
    Replies:
    2
    Views:
    375
    Eric Lilja
    Jul 6, 2006
  5. jmborr
    Replies:
    1
    Views:
    399
    Stargaming
    Nov 3, 2007
Loading...

Share This Page