digitalmars.D.bugs - [Issue 10995] New: [REG]CTFE failures for structs with void initialized members
- d-bugmail puremagic.com (53/53) Sep 08 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (22/22) Sep 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (16/18) Sep 12 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (25/27) Sep 13 2013 the field a deterministic value on initializing the field, for run-time
- d-bugmail puremagic.com (15/25) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (16/35) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (36/70) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (10/31) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (23/65) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (10/10) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
- d-bugmail puremagic.com (12/12) Sep 13 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10995
http://d.puremagic.com/issues/show_bug.cgi?id=10995 Summary: [REG]CTFE failures for structs with void initialized members Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: regression Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: monarchdodra gmail.com Regression 2.063.2 => 2.064-devel Possibly related (or even the root cause) of 10994: http://d.puremagic.com/issues/show_bug.cgi?id=10994 Let T be a struct with a void initialized member: REG 1: //---- struct T { short a = void; } enum i = T.init.a; //---- main.d(5): Error: cannot read uninitialized variable T().a in ctfe main.d(3): Error: variable main.T.a was uninitialized and used before set REG2: This one is more problematic, as there would seem to be some type system corruption: //---- struct T { short a = void; } T foo() { auto t = T.init; return t; } enum i = foo().a; //---- main.d(12): Error: couldn't find field a in short //---- Apparently, doing the call ".a" "transforms" the type of "foo()" to "a's" type, giving the cryptic error message. Or something. Both these cases passed in 2.063.2. Both these cases pass if a is not declared void-initialized. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 08 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic, ice Summary|[REG]CTFE failures for |CTFE failures for structs |structs with void |with void initialized |initialized members |members Severity|regression |normal This is not a regression. The change in behaviour is an accepts-invalid bug that was fixed. In both cases, an uninitialized variable is indeed being read. To get the intended behaviour, use -enum i = T.init.a; +enum i = T.a.init; In the first test case, the second error message is a bit useless and should be removed. And the second case, the error message is so bad it's practically a internal compiler error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 12 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995This is not a regression. The change in behaviour is an accepts-invalid bug that was fixed. In both cases, an uninitialized variable is indeed being read.I somehow expected that answer, but I'm not sure I entirely agree. Marking a field to void means the compiler is allowed to optimize out giving the field a deterministic value on initializing the field, for run-time performance reasons. But that don't mean it's not actually initialized. I think that for CTFE, it should *just work* Not being able to count on "T t = T.init" meaning "t is in an initialized state", goes against what ".init" represents. No-one said it had a deterministic value though. In any case, I think it is not that problematic. "10994" is a real blocker for me though... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 12 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995Marking a field to void means the compiler is allowed to optimize out givingthe field a deterministic value on initializing the field, for run-time performance reasons. But that don't mean it's not actually initialized. No, it's illegal. You're telling the compiler that you will initialize it. The compiler attempts to detect cases where you failed to do so, but it isn't always successful. For DMD, you need to compile with -O. struct S { int x; } void main() { S s = void; s.x++; } $ dmd -O bug bug.d(7): Error: variable s used before set The reason it seemed to be legal in structs, is that the compiler historically ignored the = void, and initialized it anyway! Now marking a field as void actually has an effect... (at least in some cases)."10994" is a real blocker for me though...Yup. I've marked that with ctfe so that it appears on my list. The fix for the diagnostics in this one is here: https://github.com/D-Programming-Language/dmd/pull/2551 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 Maxim Fomin <maxim maxim-fomin.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |maxim maxim-fomin.ru ---Marking a field of aggregate to void does different thing comparing to void initialization of variable - it makes dmd to blit memory with zeroes regardless of type (for many types default value is zero, but for some types - likes doubles and chars dmd still produces zeroes). I think CTFE should follow runtime in this regard, so in your example value of 'a' should be zero. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------This is not a regression. The change in behaviour is an accepts-invalid bug that was fixed. In both cases, an uninitialized variable is indeed being read.I somehow expected that answer, but I'm not sure I entirely agree. Marking a field to void means the compiler is allowed to optimize out giving the field a deterministic value on initializing the field, for run-time performance reasons. But that don't mean it's not actually initialized. I think that for CTFE, it should *just work*
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 ---No, it's illegal. You're telling the compiler that you will initialize it. The compiler attempts to detect cases where you failed to do so, but it isn't always successful. For DMD, you need to compile with -O. struct S { int x; } void main() { S s = void; s.x++; }This is irrelevant to the issue because it is a different case.$ dmd -O bug bug.d(7): Error: variable s used before set The reason it seemed to be legal in structs, is that the compiler historically ignored the = void, and initialized it anyway! Now marking a field as void actually has an effect... (at least in some cases).I think this point (issuing not initialized error) is wrong. Regardless of what dmd does produce in runtime (technically speaking dmd didn't ignored void initializer for fields - its presence actually affected behavior), there should be statically known default value of any type - that's why during CTFE dmd should produce some default value even for structs having void initialized fields. So, if dmd accepts this feature, it should produce some value. Not initialized type does not make much sense. It looks like initializaing some filed with void is a wired idea which doesn't fit into design, so it should be probably removed from language. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995It illustrates that it is illegal to read a value initialized to void. It is the same case, unless .init is magical. (And maybe it should be magical, see below).No, it's illegal. You're telling the compiler that you will initialize it. The compiler attempts to detect cases where you failed to do so, but it isn't always successful. For DMD, you need to compile with -O. struct S { int x; } void main() { S s = void; s.x++; }This is irrelevant to the issue because it is a different case.That's only because it's been generating extremely bad code. Intuitively, initializing a struct should be the same as initializing each member individually. struct S { int a = 2; int b = void; } S s; should mean: S s = void; S.a = S.a.init; S.b = S.b.init; and only the S.a case should generate any code. In fact, if it doesn't behave in that way, it's a completely pointless feature. (It's not an optimization).$ dmd -O bug bug.d(7): Error: variable s used before set The reason it seemed to be legal in structs, is that the compiler historically ignored the = void, and initialized it anyway! Now marking a field as void actually has an effect... (at least in some cases).I think this point (issuing not initialized error) is wrong. Regardless of what dmd does produce in runtime (technically speaking dmd didn't ignored void initializer for fields - its presence actually affected behavior),there should be statically known default value of any type - that's why during CTFE dmd should produce some default value even for structs having void initialized fields. So, if dmd accepts this feature, it should produce some value. Not initialized type does not make much sense. It looks like initializing some field with void is a weird idea which doesn't fit into design, so it should be probably removed from language.Quite possibly. It's a fight: .init gives what it was initialized with. 'void' says it's not initialized! They can't both be true! Certainly the current runtime behaviour (blitting zeros onto the struct) is useless. Another possible resolution would be to define .init to mean "the value the object would be initialized to, with = void treated as the default initializer. This would however mean that: S s; and S s = S.init; would not be the same, in the case where a void initializer is present. Of course they are different anyway, if a constructor is present. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995Just for the record, you should never initialize a struct instance like this. If you do this, then the padding bytes will not be initialized. This is important, as if S has no elaborate opEquals, comparison becomes a straight up memcompare, which will unconditonally scan the totality of S, padding and all. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------I think this point (issuing not initialized error) is wrong. Regardless of what dmd does produce in runtime (technically speaking dmd didn't ignored void initializer for fields - its presence actually affected behavior),That's only because it's been generating extremely bad code. Intuitively, initializing a struct should be the same as initializing each member individually. struct S { int a = 2; int b = void; } S s; should mean: S s = void; S.a = S.a.init; S.b = S.b.init; and only the S.a case should generate any code.
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 ---In case of particular variable void initialization there is no questions regarding default value of type per se, its semantic is clear and there is consensus regarding it. However in case of field initialization, usecase affects not some variable but type of variable (which is essential point here) and as consequence, all instances of that type. And there is no consensus on what does this feature mean. That's why I ask to concentrate on field void initialization.This is irrelevant to the issue because it is a different case.It illustrates that it is illegal to read a value initialized to void. It is the same case, unless .init is magical. (And maybe it should be magical, see below).That's only because it's been generating extremely bad code. Intuitively, initializing a struct should be the same as initializing each member individually. struct S { int a = 2; int b = void; } S s; should mean: S s = void; S.a = S.a.init; S.b = S.b.init; and only the S.a case should generate any code. In fact, if it doesn't behave in that way, it's a completely pointless feature. (It's not an optimization).Yes, this behavior makes sense. There is one question left - what is default value of type S in CT, in particular what static assert(S.init.a == ??) should be.Yes.It looks like initializing some field with void is a weird idea which doesn't fit into design, so it should be probably removed from language.Quite possibly. It's a fight: .init gives what it was initialized with. 'void' says it's not initialized! They can't both be true!Certainly the current runtime behaviour (blitting zeros onto the struct) is useless.Yes.Another possible resolution would be to define .init to mean "the value the object would be initialized to, with = void treated as the default initializer. This would however mean that: S s; and S s = S.init; would not be the same, in the case where a void initializer is present. Of course they are different anyway, if a constructor is present.I think this is better option than current situation. Init value of aggregate with void field should give default value of respective type. If it does provide in CT zeroes irrespective of type, it is useless, if it doesn't yield anything at all, than it badly integrates into language design and should not be supported at all. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/a65d3247bf1e2443f2ed4c1632cf5b032edf78d3 Fix bug 10995 CTFE failure for void initialized members Fix the duplicate error message, and don't scrub twice -- only scrub when CTFE is actually finished. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10995 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |bugzilla digitalmars.com Resolution| |FIXED 10:54:14 PDT --- https://github.com/D-Programming-Language/dmd/pull/2551 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 13 2013