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