www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is it intentional that forward references in unittests aren't

reply Trass3r <un known.com> writes:
void main()
{
}

unittest
{
	struct S
	{
		S2 s;
	}
	
	struct S2
	{
	}
	
	S s;
}

yields:
unittests.d(9): Error: identifier 'S2' is not defined
unittests.d(9): Error: S2 is used as a type
unittests.d(8): Error: no size for type _error_
Error: no size for type _error_


while putting S2 in front of S works makes it work.

Is this intentional?
Jun 03 2010
next sibling parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 06/03/2010 05:04 PM, Trass3r wrote:
 void main()
 {
 }

 unittest
 {
 struct S
 {
 S2 s;
 }

 struct S2
 {
 }

 S s;
 }

 yields:
 unittests.d(9): Error: identifier 'S2' is not defined
 unittests.d(9): Error: S2 is used as a type
 unittests.d(8): Error: no size for type _error_
 Error: no size for type _error_


 while putting S2 in front of S works makes it work.

 Is this intentional?

It's intentional. Forward references generally aren't allowed inside function bodies.
Jun 03 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Trass3r:

 void main()
 {
 }
 
 unittest
 {
 	struct S
 	{
 		S2 s;
 	}

Being unittests functions, it can be better to use "static struct" there instead of "struct". ------------------------- Ellery Newcomer:
 It's intentional. Forward references generally aren't allowed inside 
 function bodies.

Unittests being normal functions is an abstraction that leaks a bit, but I presume it's OK. Bye, bearophile
Jun 03 2010
parent bearophile <bearophileHUGS lycos.com> writes:
retard:
 What does this mean? Can't you write a wrapper struct/class inside the 
 block if you don't want to expose S and S2 outside the unittest block.

Seen from a high level a unittest section != function. But in D they are implemented as a kind-of-function anyway. So unittests in D2 can show some unwanted characteristics that are present in functions. This means that they are an abstraction that "leaks" (a bit): http://en.wikipedia.org/wiki/Leaky_abstraction But I have not criticized this design choice because overall the alternatives can be worse. Bye, bearophile
Jun 03 2010
prev sibling next sibling parent retard <re tard.com.invalid> writes:
Thu, 03 Jun 2010 18:30:04 -0400, bearophile wrote:

 Trass3r:
 
 void main()
 {
 }
 
 unittest
 {
 	struct S
 	{
 		S2 s;
 	}

Being unittests functions, it can be better to use "static struct" there instead of "struct". ------------------------- Ellery Newcomer:
 It's intentional. Forward references generally aren't allowed inside
 function bodies.

Unittests being normal functions is an abstraction that leaks a bit, but I presume it's OK.

What does this mean? Can't you write a wrapper struct/class inside the block if you don't want to expose S and S2 outside the unittest block.
Jun 03 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 03 Jun 2010 18:04:26 -0400, Trass3r <un known.com> wrote:

 void main()
 {
 }

 unittest
 {
 	struct S
 	{
 		S2 s;
 	}
 	
 	struct S2
 	{
 	}
 	
 	S s;
 }

 yields:
 unittests.d(9): Error: identifier 'S2' is not defined
 unittests.d(9): Error: S2 is used as a type
 unittests.d(8): Error: no size for type _error_
 Error: no size for type _error_


 while putting S2 in front of S works makes it work.

 Is this intentional?

unittest is a function. It's basically a single function per module that is a concatenation of all the unit tests in the module. Inside functions, forward references are not allowed. You can declare types or include imports using version(unittest) and then forward references should work. -Steve
Jun 04 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 03 Jun 2010 20:44:00 -0400, retard <re tard.com.invalid> wrote:

 Thu, 03 Jun 2010 18:30:04 -0400, bearophile wrote:

 Trass3r:

 void main()
 {
 }

 unittest
 {
 	struct S
 	{
 		S2 s;
 	}

Being unittests functions, it can be better to use "static struct" there instead of "struct". ------------------------- Ellery Newcomer:
 It's intentional. Forward references generally aren't allowed inside
 function bodies.

Unittests being normal functions is an abstraction that leaks a bit, but I presume it's OK.

What does this mean? Can't you write a wrapper struct/class inside the block if you don't want to expose S and S2 outside the unittest block.

When compiling unittests, the version 'unittest' is defined, so something like this should work: version(unittest) { struct S { S2 s; } struct S2 {} } -Steve
Jun 04 2010