Puzzled by this behavior
H. S. Teoh
hsteoh at qfbox.info
Tue May 31 17:59:43 UTC 2022
On Tue, May 31, 2022 at 05:41:18PM +0000, Don Allen via Digitalmars-d wrote:
> This
>
> ````
> import std.stdio;
>
> void foo() {
> bar();
> }
> void bar() {
> writeln("Hello world");
> }
> int main(string[] args)
> {
> foo();
> return 0;
> }
> ````
>
> compiles and does what you'd expect, despite the forward reference from foo
> to bar, which, of course, would not work in C.
>
> But
> ````
> import std.stdio;
>
> int main(string[] args)
> {
> void foo() {
> bar();
> }
> void bar() {
> writeln("Hello world");
> }
> foo();
> return 0;
> }
> ````
> gives the error
> ````
> (dmd-2.100.0)dca at pangloss.allen.net:/home/dca/Software/d_tests$ dmd test5.d
> test5.d(6): Error: undefined identifier `bar`
> ````
> This only works if you interchange the order of foo and bar,
> eliminating the forward reference.
>
> This strikes me as pretty inconsistent behavior, especially to someone
> who has written as much Scheme and Haskell as I have. I've also not
> found it documented, though I could have missed it (if someone could
> point me to where this is discussed, I'd appreciate it). My main
> purpose in sending this message is to understand whether this is a bug
> or a documented "feature". If the former, I will file a bug report.
[...]
This is expected. In module scope, D tries as much as possible to
eliminate forward reference issues. (There are some buggy/inconsistent
cases, but those are generally rare unless you're doing something
unusual.)
Inside function scope, however, it was deemed impractical because of
closure over local variables:
void myfunc() {
int x;
void woohoo() {
x++; // this is legal, closes over x
}
...
}
Had out-of-order declaration been allowed, it would have been rather
confusing:
void myfunc() {
void woohoo() {
x++; // should this close over 'x' inside the 'if'?
}
if (someWeirdCondition) {
int x;
}
}
This potentially becomes worse when imported symbols are involved.
Hence, it was decided that inside function scope you must declare all
symbols before referring to them, unlike module scope.
T
--
LINUX = Lousy Interface for Nefarious Unix Xenophobes.
More information about the Digitalmars-d
mailing list