digitalmars.D - "ubyte[size] store = void" in std.variant
- Graham Fawcett <fawcett uwindsor.ca> Jun 15 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Jun 15 2010
- bearophile <bearophileHUGS lycos.com> Jun 15 2010
- Graham Fawcett <fawcett uwindsor.ca> Jun 15 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Jun 15 2010
- Graham Fawcett <fawcett uwindsor.ca> Jun 15 2010
- Graham Fawcett <fawcett uwindsor.ca> Jun 15 2010
- Graham Fawcett <fawcett uwindsor.ca> Jun 15 2010
Hi folks,
The following statement appears in std.variant:
190 union
191 {
192 ubyte[size] store = void;
193 // conservatively mark the region as pointers
194 static if (size >= (void*).sizeof)
195 void* p[size / (void*).sizeof];
196 }
The '= void' on line 192 sometimes leads to 'Error: void initializer
has no value' errors in application code. For example, this fails to
compile on DMD 2.047:
foreach (int v; map! "a.get!int" (variantArray(1,2,3)))
writeln(v);
Changing line 192 to 'ubyte[size] store;' resolves the issue.
My question is: what is the point of the '= void' initializer here?
Would std.variant be broken if '= void' were removed?
Thanks,
Graham
Jun 15 2010
On Tue, 15 Jun 2010 09:04:23 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:Hi folks, The following statement appears in std.variant: 190 union 191 { 192 ubyte[size] store = void; 193 // conservatively mark the region as pointers 194 static if (size >= (void*).sizeof) 195 void* p[size / (void*).sizeof]; 196 } The '= void' on line 192 sometimes leads to 'Error: void initializer has no value' errors in application code. For example, this fails to compile on DMD 2.047: foreach (int v; map! "a.get!int" (variantArray(1,2,3))) writeln(v); Changing line 192 to 'ubyte[size] store;' resolves the issue. My question is: what is the point of the '= void' initializer here? Would std.variant be broken if '= void' were removed?
= void means don't initialize the data. Otherwise, the compiler/runtime will fill in the data will all 0s. However, I'm not sure how that works with a union, since you may have conflicting requirements for initialization. Is there a place in the spec that covers this? -Steve
Jun 15 2010
Graham Fawcett:struct foo { enum N = 10; // or whatever ubyte[N] store = void; } foo z = foo();
I think there's a bug there, you can add it to Bugzilla (if not already present): struct Foo { int[1] a = void; } void main() { Foo f = Foo(); } Bye, bearophile
Jun 15 2010
On Tue, 15 Jun 2010 10:29:56 -0400, Steven Schveighoffer wrote:On Tue, 15 Jun 2010 09:04:23 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:Hi folks, The following statement appears in std.variant: 190 union 191 { 192 ubyte[size] store = void; 193 // conservatively mark the region as pointers 194 static if (size >= (void*).sizeof) 195 void* p[size / (void*).sizeof]; 196 } The '= void' on line 192 sometimes leads to 'Error: void initializer has no value' errors in application code. For example, this fails to compile on DMD 2.047: foreach (int v; map! "a.get!int" (variantArray(1,2,3))) writeln(v); Changing line 192 to 'ubyte[size] store;' resolves the issue. My question is: what is the point of the '= void' initializer here? Would std.variant be broken if '= void' were removed?
= void means don't initialize the data. Otherwise, the compiler/runtime will fill in the data will all 0s. However, I'm not sure how that works with a union, since you may have conflicting requirements for initialization.
I'm not sure if it's in the spec, but a quick test results in a compiler error if I declare a union with overlapping initializers. Simplifying the 'std.variant' case, I get the same 'void initializer has no value' error like this: struct foo { ubyte[] store = void; } foo z = foo(); Is this a compiler bug? Graham
Jun 15 2010
On Tue, 15 Jun 2010 11:18:07 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:On Tue, 15 Jun 2010 10:29:56 -0400, Steven Schveighoffer wrote:On Tue, 15 Jun 2010 09:04:23 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:Hi folks, The following statement appears in std.variant: 190 union 191 { 192 ubyte[size] store = void; 193 // conservatively mark the region as pointers 194 static if (size >= (void*).sizeof) 195 void* p[size / (void*).sizeof]; 196 } The '= void' on line 192 sometimes leads to 'Error: void initializer has no value' errors in application code. For example, this fails to compile on DMD 2.047: foreach (int v; map! "a.get!int" (variantArray(1,2,3))) writeln(v); Changing line 192 to 'ubyte[size] store;' resolves the issue. My question is: what is the point of the '= void' initializer here? Would std.variant be broken if '= void' were removed?
= void means don't initialize the data. Otherwise, the compiler/runtime will fill in the data will all 0s. However, I'm not sure how that works with a union, since you may have conflicting requirements for initialization.
I'm not sure if it's in the spec, but a quick test results in a compiler error if I declare a union with overlapping initializers. Simplifying the 'std.variant' case, I get the same 'void initializer has no value' error like this: struct foo { ubyte[] store = void; } foo z = foo(); Is this a compiler bug?
Note, you can only use = void on a value type, not a dynamic array. The variant union member is a static array, not a dynamic one. But actually, now that I think about it, =void is generally used in a function, not in a type definition. I'm not sure = void should be allowed in that context. So maybe the compiler is right to complain... -Steve
Jun 15 2010
On Tue, 15 Jun 2010 11:24:48 -0400, Steven Schveighoffer wrote:On Tue, 15 Jun 2010 11:18:07 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:On Tue, 15 Jun 2010 10:29:56 -0400, Steven Schveighoffer wrote:On Tue, 15 Jun 2010 09:04:23 -0400, Graham Fawcett <fawcett uwindsor.ca> wrote:Hi folks, The following statement appears in std.variant: 190 union 191 { 192 ubyte[size] store = void; 193 // conservatively mark the region as pointers 194 static if (size >= (void*).sizeof) 195 void* p[size / (void*).sizeof]; 196 } The '= void' on line 192 sometimes leads to 'Error: void initializer has no value' errors in application code. For example, this fails to compile on DMD 2.047: foreach (int v; map! "a.get!int" (variantArray(1,2,3))) writeln(v); Changing line 192 to 'ubyte[size] store;' resolves the issue. My question is: what is the point of the '= void' initializer here? Would std.variant be broken if '= void' were removed?
= void means don't initialize the data. Otherwise, the compiler/runtime will fill in the data will all 0s. However, I'm not sure how that works with a union, since you may have conflicting requirements for initialization.
I'm not sure if it's in the spec, but a quick test results in a compiler error if I declare a union with overlapping initializers. Simplifying the 'std.variant' case, I get the same 'void initializer has no value' error like this: struct foo { ubyte[] store = void; } foo z = foo(); Is this a compiler bug?
Note, you can only use = void on a value type, not a dynamic array. The variant union member is a static array, not a dynamic one.
Oops, thanks for catching that. I was trying various combinations of types and array-sizes to look for a pattern. For the record, struct foo { enum N = 10; // or whatever ubyte[N] store = void; } foo z = foo(); ...returns the same error. GrahamBut actually, now that I think about it, =void is generally used in a function, not in a type definition. I'm not sure = void should be allowed in that context. So maybe the compiler is right to complain... -Steve
Jun 15 2010
On Tue, 15 Jun 2010 13:24:07 -0400, bearophile wrote:Graham Fawcett:struct foo { enum N = 10; // or whatever ubyte[N] store = void; } foo z = foo();
I think there's a bug there, you can add it to Bugzilla (if not already present): struct Foo { int[1] a = void; } void main() { Foo f = Foo(); } Bye, bearophile
OK, added. http://d.puremagic.com/issues/show_bug.cgi?id=4322 "void initializer has no value" on struct/union members initialized to "void" Thanks, Graham
Jun 15 2010
On Tue, 15 Jun 2010 17:39:50 +0000, Graham Fawcett wrote:On Tue, 15 Jun 2010 13:24:07 -0400, bearophile wrote:Graham Fawcett:struct foo { enum N = 10; // or whatever ubyte[N] store = void; } foo z = foo();
I think there's a bug there, you can add it to Bugzilla (if not already present): struct Foo { int[1] a = void; } void main() { Foo f = Foo(); } Bye, bearophile
OK, added. http://d.puremagic.com/issues/show_bug.cgi?id=4322 "void initializer has no value" on struct/union members initialized to "void" Thanks, Graham
FWIW, removing line 100 in init.c allows our simple examples to compile and run correctly. Of course I'm not 100% clear on why the error message was there in the first place. :) diff --git a/trunk/src/init.c b/trunk/src/init.c index ed3a091..cf9bc72 100644 --- a/trunk/src/init.c +++ b/trunk/src/init.c -97,7 +97,6 Initializer *VoidInitializer::semantic(Scope *sc, Type *t) Expression *VoidInitializer::toExpression() { - error(loc, "void initializer has no value"); return new IntegerExp(0); } best, Graham
Jun 15 2010









bearophile <bearophileHUGS lycos.com> 