Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > function default arguments from other arguments

Reply
Thread Tools

function default arguments from other arguments

 
 
tutmann
Guest
Posts: n/a
 
      10-17-2006
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

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-17-2006
* 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?
 
Reply With Quote
 
 
 
 
Bart
Guest
Posts: n/a
 
      10-17-2006
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.

 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      10-17-2006

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.

 
Reply With Quote
 
Bart
Guest
Posts: n/a
 
      10-17-2006
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.

 
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
how to pass a function name and its arguments inside the arguments of other function? jmborr Python 1 11-03-2007 08:20 AM
Default arguments, one call compiles, the other does not Eric Lilja C++ 2 07-06-2006 12:51 AM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Difference between default arguments and keyword arguments Edward Diener Python 14 04-05-2004 11:26 PM
Is it legal that a function pointer to "function with default arguments"? Ajax Chelsea C++ 1 12-02-2003 02:01 PM



Advertisments