|
Archives
D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
|
D - Functions in default args
↑ ↓ ← → Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
What is/will be the D standard for how function calls as default
arguments? Will the function be evaluated once, then saved, or
re-called each time, or what?
I tried this on gcc, and got some very weird results:
SOURCE:
#include <stdio.h>
class X
{
public:
X() { printf("X::X %p\n",this); };
~X() { printf("X::~X %p\n",this); };
};
class FOO
{
public:
FOO(X *ptr = new X) { printf("FOO::FOO(%p) %p\n",ptr,this); };
~FOO() { printf("FOO::~FOO %p\n",this); };
};
int main()
{
FOO a;
FOO b;
X c;
FOO d(&c);
return 0;
};
OUTPUT (compiled by gcc):
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc17
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc16
X::X 0xbffffc15
FOO::FOO(0xbffffc15) 0xbffffc14
FOO::~FOO 0xbffffc14
X::~X 0xbffffc15
FOO::~FOO 0xbffffc16
FOO::~FOO 0xbffffc17
That is *really* bad. That's why I don't use function in default
arguments in C++.
--
The Villagers are Online! villagersonline.com
.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
↑ ↓ ← → "Walter" <walter digitalmars.com> writes:
Default arguments are not allowed in D. To achieve the same effect as C++:
void foo(int i, int j = 3);
in D:
void foo(int i, int j);
void foo(int i) { foo(i, 3); }
Inlining and optimization will produce the same code, without the
ambiguities and surprising behavior (as you discovered) of C++.
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BE9DF39.D513D6BE deming-os.org...
What is/will be the D standard for how function calls as default
arguments? Will the function be evaluated once, then saved, or
re-called each time, or what?
I tried this on gcc, and got some very weird results:
SOURCE:
#include <stdio.h>
class X
{
public:
X() { printf("X::X %p\n",this); };
~X() { printf("X::~X %p\n",this); };
};
class FOO
{
public:
FOO(X *ptr = new X) { printf("FOO::FOO(%p) %p\n",ptr,this); };
~FOO() { printf("FOO::~FOO %p\n",this); };
};
int main()
{
FOO a;
FOO b;
X c;
FOO d(&c);
return 0;
};
OUTPUT (compiled by gcc):
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc17
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc16
X::X 0xbffffc15
FOO::FOO(0xbffffc15) 0xbffffc14
FOO::~FOO 0xbffffc14
X::~X 0xbffffc15
FOO::~FOO 0xbffffc16
FOO::~FOO 0xbffffc17
That is *really* bad. That's why I don't use function in default
arguments in C++.
--
The Villagers are Online! villagersonline.com
.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
↑ ↓ ← → "Pavel \"EvilOne\" Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9sdc1v$2167$2 digitaldaemon.com...
Default arguments are not allowed in D. To achieve the same effect as C++:
Why? =(
Inlining and optimization will produce the same code, without the
ambiguities and surprising behavior (as you discovered) of C++.
Um... why not restrict default arguments to be compile-time constants
only? This would resolve any "surprising behaviour" unclearance.
As for ambiguity... that's something that we have to live with if
we use function overloading, optional arguments don't actually add
much to it, but they can be so damn useful. Yes, they can be emulated
by overloading, as you've stated, but why not throw a bit of
(syntactic) sugar in?
↑ ↓ ← → Roland <rv ronetech.com> writes:
Default argument can be put in the same categorie as operator overloading: the
"sugar" categorie.
Personaly, i don't know how i can live without operator overloading sugar.
But the more i get experienced, the less i use default argument sugar, never for
new code.
I think default argument is a good way to make mistake: you forget an argument
and the compiler
put one that is not good.
Roland
Pavel \"EvilOne\" Minayev a écrit :
"Walter" <walter digitalmars.com> wrote in message
news:9sdc1v$2167$2 digitaldaemon.com...
Default arguments are not allowed in D. To achieve the same effect as C++:
Why? =(
Inlining and optimization will produce the same code, without the
ambiguities and surprising behavior (as you discovered) of C++.
Um... why not restrict default arguments to be compile-time constants
only? This would resolve any "surprising behaviour" unclearance.
As for ambiguity... that's something that we have to live with if
we use function overloading, optional arguments don't actually add
much to it, but they can be so damn useful. Yes, they can be emulated
by overloading, as you've stated, but why not throw a bit of
(syntactic) sugar in?
↑ ↓ ← → "Pavel \"EvilOne\" Minayev" <evilone omen.ru> writes:
"Roland" <rv ronetech.com> wrote in message
news:3BEBD5A0.B7D7D9DF ronetech.com...
Default argument can be put in the same categorie as operator overloading:
"sugar" categorie.
Personaly, i don't know how i can live without operator overloading sugar.
But the more i get experienced, the less i use default argument sugar,
new code.
I think default argument is a good way to make mistake: you forget an
and the compiler
put one that is not good.
If it is an issue, why use default arguments in your programs at all?
Sometimes, however, they can be useful. Imagine a File class which
has Seek method, similar to fseek():
function Seek(int offset, int whence = SEEK_SET);
Now when you simply want to move to some position in file (which is
90% of all uses), you use a simple and logical Seek(123) syntax. In
other words, a generic rule for optional arguments, "use them only
when the default behaviour is absolutely clear" - like in case with
Seek(). Of course, using this feature improperly may result in poor
reliability and readability, but the same problem is with function
overloading, heck, even OOP!
↑ ↓ ← → Roland <rv ronetech.com> writes:
Pavel \"EvilOne\" Minayev a écrit :
If it is an issue, why use default arguments in your programs at all?
Sometimes, however, they can be useful. Imagine a File class which
has Seek method, similar to fseek():
function Seek(int offset, int whence = SEEK_SET);
Now when you simply want to move to some position in file (which is
90% of all uses), you use a simple and logical Seek(123) syntax. In
other words, a generic rule for optional arguments, "use them only
when the default behaviour is absolutely clear" - like in case with
Seek(). Of course, using this feature improperly may result in poor
reliability and readability, but the same problem is with function
overloading, heck, even OOP!
In fact i agree with you.
But one issue of D is to force programmer to make standardized code,
understandable, easy to maintant.
One ultimate goal as far as i understand is: one thing to do, only one way to
write the code.
So it is a question of balance. If compiler is too restrictive, few will use it
or people will create preprocessor for
it. If it is too flexible, why not keep C++ ?
The ideal would be: "if default argument behaviour is absolutely clear" then
compile else throw a compiler error.
A lot of work for Walter..
Roland
↑ ↓ ← → "Pavel \"EvilOne\" Minayev" <evilone omen.ru> writes:
"Roland" <rv ronetech.com> wrote in message
news:3BEC408C.839137B3 ronetech.com...
The ideal would be: "if default argument behaviour is absolutely clear"
compile else throw a compiler error.
A lot of work for Walter..
Yeah, writing an AI system to determine the expected default
behaviour from function names =)
↑ ↓ ← → "Sean L. Palmer" <spalmer iname.com> writes:
I'm with Pavel... I can understand limiting default arguments to
compile-time constant expressions only, but are you sure you want to replace
the default syntax by a requirement that the programmer make 'n' copies of
the function which all forward to the one with the most parameters
(maintenance headache) or forward to the one with one more parameter (the
optimizer will have to do more work), where 'n' is the number of default
parameters? If you were maintaining a piece of code, and you came across
one of these, which would you rather it look like:?
class A
{
this(int a=0, int b=1, int c=2, int d=3) { PaintByNumbers(a,b,c,d); }
}
or this:
class B
{
this() { this(0,1,2,3); }
this(int a) { this(a,1,2,3); }
this(int a, int b) { this(a,b,2,3); }
this(int a, int b, int c) { this(a,b,c,3); }
this(int a, int b, int c, int d) { PaintByNumbers(a,b,c,d); }
}
I'm sure you can extrapolate out a bit based on past experiences. ;)
Surely any ambiguities with conflicting signatures can be resolved. This is
one feature C++ has I don't get troubled by often. It sure is convenient
though... extra convenient since in C++ you could only have the defaults in
the function declaration, not the definition, and D merges those two things.
Sean
"Walter" <walter digitalmars.com> wrote in message
news:9sdc1v$2167$2 digitaldaemon.com...
Default arguments are not allowed in D. To achieve the same effect as C++:
void foo(int i, int j = 3);
in D:
void foo(int i, int j);
void foo(int i) { foo(i, 3); }
Inlining and optimization will produce the same code, without the
ambiguities and surprising behavior (as you discovered) of C++.
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BE9DF39.D513D6BE deming-os.org...
What is/will be the D standard for how function calls as default
arguments? Will the function be evaluated once, then saved, or
re-called each time, or what?
I tried this on gcc, and got some very weird results:
SOURCE:
#include <stdio.h>
class X
{
public:
X() { printf("X::X %p\n",this); };
~X() { printf("X::~X %p\n",this); };
};
class FOO
{
public:
FOO(X *ptr = new X) { printf("FOO::FOO(%p) %p\n",ptr,this); };
~FOO() { printf("FOO::~FOO %p\n",this); };
};
int main()
{
FOO a;
FOO b;
X c;
FOO d(&c);
return 0;
};
OUTPUT (compiled by gcc):
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc17
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc16
X::X 0xbffffc15
FOO::FOO(0xbffffc15) 0xbffffc14
FOO::~FOO 0xbffffc14
X::~X 0xbffffc15
FOO::~FOO 0xbffffc16
FOO::~FOO 0xbffffc17
That is *really* bad. That's why I don't use function in default
arguments in C++.
--
The Villagers are Online! villagersonline.com
.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
↑ ↓ ← → "Walter" <walter digitalmars.com> writes:
There's also the issue of what do you do with the default argument when the
function is overridden in a derived class. I'd rather just avoid the
complexity and the special rules. I don't like looking at the function call,
and then having to look at the derived class to see what the function does,
and then look at the base class to see what the arguments are, ...
I admit it's a matter of personal taste.
"Sean L. Palmer" <spalmer iname.com> wrote in message
news:9sdoi0$2app$1 digitaldaemon.com...
I'm with Pavel... I can understand limiting default arguments to
compile-time constant expressions only, but are you sure you want to
the default syntax by a requirement that the programmer make 'n' copies of
the function which all forward to the one with the most parameters
(maintenance headache) or forward to the one with one more parameter (the
optimizer will have to do more work), where 'n' is the number of default
parameters? If you were maintaining a piece of code, and you came across
one of these, which would you rather it look like:?
class A
{
this(int a=0, int b=1, int c=2, int d=3) { PaintByNumbers(a,b,c,d); }
}
or this:
class B
{
this() { this(0,1,2,3); }
this(int a) { this(a,1,2,3); }
this(int a, int b) { this(a,b,2,3); }
this(int a, int b, int c) { this(a,b,c,3); }
this(int a, int b, int c, int d) { PaintByNumbers(a,b,c,d); }
}
I'm sure you can extrapolate out a bit based on past experiences. ;)
Surely any ambiguities with conflicting signatures can be resolved. This
one feature C++ has I don't get troubled by often. It sure is convenient
though... extra convenient since in C++ you could only have the defaults
the function declaration, not the definition, and D merges those two
Sean
"Walter" <walter digitalmars.com> wrote in message
news:9sdc1v$2167$2 digitaldaemon.com...
Default arguments are not allowed in D. To achieve the same effect as
void foo(int i, int j = 3);
in D:
void foo(int i, int j);
void foo(int i) { foo(i, 3); }
Inlining and optimization will produce the same code, without the
ambiguities and surprising behavior (as you discovered) of C++.
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BE9DF39.D513D6BE deming-os.org...
What is/will be the D standard for how function calls as default
arguments? Will the function be evaluated once, then saved, or
re-called each time, or what?
I tried this on gcc, and got some very weird results:
SOURCE:
#include <stdio.h>
class X
{
public:
X() { printf("X::X %p\n",this); };
~X() { printf("X::~X %p\n",this); };
};
class FOO
{
public:
FOO(X *ptr = new X) { printf("FOO::FOO(%p) %p\n",ptr,this); };
~FOO() { printf("FOO::~FOO %p\n",this); };
};
int main()
{
FOO a;
FOO b;
X c;
FOO d(&c);
return 0;
};
OUTPUT (compiled by gcc):
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc17
X::X 0x8049c08
FOO::FOO(0x8049c08) 0xbffffc16
X::X 0xbffffc15
FOO::FOO(0xbffffc15) 0xbffffc14
FOO::~FOO 0xbffffc14
X::~X 0xbffffc15
FOO::~FOO 0xbffffc16
FOO::~FOO 0xbffffc17
That is *really* bad. That's why I don't use function in default
arguments in C++.
--
The Villagers are Online! villagersonline.com
.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
↑ ↓ ← → a <a b.c> writes:
Walter wrote:
There's also the issue of what do you do with the default argument when the
function is overridden in a derived class. I'd rather just avoid the
complexity and the special rules. I don't like looking at the function call,
and then having to look at the derived class to see what the function does,
and then look at the base class to see what the arguments are, ...
I admit it's a matter of personal taste.
Given that, you have to be aware that it will almost certainly be an
'extension' in the first open source compiler anyway.
As far as not wanting to look at the derived class, if a person is
already going to need specialized tools and editors to extract a
stripped down/opaque interface for a class (no header files) then the
same tools can be made to determine which version of the function is
being called. Granted I hate when a language requires the use of
specialized editors or IDE, but other decisions have already been made
make it necessary to use such beasts with D. Put this feature in that
category. We all like to program in a word processor anyway, right?
Dan
|
|