Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!uvaarpa!mcnc!rti!xyzzy!bigbird.rtp.dg.com!langley From: langley@bigbird.rtp.dg.com (Mark L Langley) Newsgroups: comp.lang.c++ Subject: default argument discussion Message-ID: <1006@xyzzy.UUCP> Date: 8 Mar 90 12:07:50 GMT Sender: usenet@xyzzy.UUCP Reply-To: langley@bigbird.rtp.dg.com (Mark L Langley) Organization: Data General Corporation, Research Triangle Park, NC Lines: 100 jak@cs.brown.edu writes > >langley@bigbird.rtp.dg.com (Mark L Langley) suggests that the following >should be legal: >> >> void bar(int x=i+j) { >> printf("%d\n", x); >> } >> >> main() { >> int i=20, j=30; >> bar(); >> } >> ...I intend to propose this as a change in ANSI C++, and have already >> proposed it to AT&T in private correspondance... > >Surely you can't be serious about this? You are proposing dynamic >scoping for C++. C and C++ have always been lexically scoped, and the >problems with dynamic scoping are so great that languages like Lisp, >which used to be dynamically scoped, are moving away from it. Yes I am serious, but no, I am not *proposing dynamic scoping*. I am just proposing that you delay evaluating the arguments until you evaluate the function call. Apparently I didn't make my point very clear; in retrospect I chose a poor example. Perhaps I am suggesting a slight mind shift. Namely, the default argument is not (I suggest) a property of the function definition. Rather it is a property of the caller. I think this is a better way of looking at it for two reasons. First, since the caller is the one that provides the arguments, shouldn't he have some say (if he wants it) in the arguments he *doesn't* provide? Second, I think that this is more compatible with the usual conventions of name-shadowing. Simply look at the declaration of the function as a scoped name, and more local declarations may shadow it. This imposes no new constraints on the user (he can just use the declaration from the include file unless he has something in mind). > >Consider: > >- How can you guarantee that any i and j will be in scope when bar is >called? You would have to look at the context of every call to bar to >decide this. If there is no i or j visible, then i and j are undeclared identifiers, and this should be reported as an error. > >- How do you decide which i and j should be used? You have to scan up >the stack at run-time -- a very expensive proposition. > >- How can you do any reasoning on your program when you have no idea >which i and j are going to be used? > No such mechanism is required. You take the most local copies of i and j at call time, the same as in any other expression. Now I wouldn't really expect someone to put foo(int x=i+j) {} in the function definition -- this would probably be a misuse. Rather, I would more expect some user of foo (a regular user at that) to supply some more appropriate value than the generic default. Consider this // foo.h void foo(int operation_type=0); ... // Delete.h #include foo.h enum MajorOptype { Noop, Insert=100, Delete=200 }; void foo(int operation_type=Delete); // application.c #include Delete.h enum MinorOptype { Paragraph, Word, Line, Column }; // big function bar with LOTS of calls to foo insert_from_deleted_buffer() { extern void foo(int operation_type=major_operation + minor_operation); const int major_operation=Insert; enum MinorOptype minor_operation; foo(); } > Jak >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >ARPA/BITNET : jak@cs.brown.edu Tel : (401) 863 7664 >Snail : 86 Benevolent St, Providence, 02906 RI. Tel : (401) 272 6149 Mark Langley langley@dg-rtp.dg.com -- Creative dissent always encouraged --