Bug 13678 – TypeInfo.initializer is inconsistent

Status
NEW
Severity
minor
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2014-11-04T07:08:58Z
Last change time
2024-12-13T18:32:32Z
Assigned to
No Owner
Creator
Marco Leise
Moved to GitHub: dmd#18904 →

Comments

Comment #0 by Marco.Leise — 2014-11-04T07:08:58Z
Related to issue #7319 I wrote this program: ---------8<------------- import std.typetuple; import std.stdio; struct StuffDefault(T) { T[1024 * 1024] m_data; } struct StuffVoid(T) { T[1024 * 1024] m_data = void; } struct StuffZero(T) { T[1024 * 1024] m_data = 0; } void main(string[] args) { alias Ts = TypeTuple!( StuffDefault!void, StuffVoid!void, StuffDefault!ubyte, StuffVoid!ubyte, StuffZero!ubyte, StuffVoid!char, StuffZero!char, ); // .inits visible at runtime foreach (T; Ts) { writefln("Does %s have a superfluous init? %s", T.stringof, typeid(T).init.ptr is null ? "no" : "YES"); } } ----------->8------------ Prints: Does StuffDefault!void have a superfluous init? no Does StuffVoid!void have a superfluous init? YES Does StuffDefault!ubyte have a superfluous init? no Does StuffVoid!ubyte have a superfluous init? YES Does StuffZero!ubyte have a superfluous init? YES Does StuffVoid!char have a superfluous init? YES Does StuffZero!char have a superfluous init? YES Ironically initializing things as void /creates/ a .init in the TypeInfo in the first place. It is inconsistent and I don't know if there was a plan behind when .init.ptr is null, but it shouldn't be available on void-initialized variables. What's the use case of TypeInfo.init ? To circumvent the type system in preparing a memory location for a struct or class, such as emplacing them in an malloc'd block/array. For that to work we want to know: Is the initializer void? -> Do nothing. Is the initializer all zeroes? -> memset(p, 0, sz); Otherwise -> memcpy(p, init.ptr, init.length); If supporting all three is infeasible, the 2nd case should go. I.e.: TypeInfo.init.ptr is only unset for void initializers. In addition I think I saw one of the TypeInfo_<xyz>.init return a ubyte[] instead of a void[]. So void[] = typeid(T).init would not work. If someone takes on this bug, they might want to look into this as well and make it consistent.
Comment #1 by slavo5150 — 2015-07-02T00:56:13Z
Comment #2 by schveiguy — 2015-12-15T15:13:32Z
init.ptr is null means that the data should be initialized to zero. As far as I know, there is no mechanism to say you shouldn't initialize the data. That being said, I can agree that all of the cases above should have null pointers for init (soon to be called initializer). No reason to store those zeros in the data segment.
Comment #3 by Marco.Leise — 2016-01-18T04:24:04Z
(In reply to Steven Schveighoffer from comment #2) > As far as I know, there is no mechanism to say you shouldn't initialize the > data. That is correct and my thinking is that this was due to the .init/.initializer property being underspecified, since we do have it in the language: struct Output { double[1024] data = void; } Instead of: null => initializer is all zeroes array of correct length => initializer contains non-zero bytes we could also define three states: ptr is null, length is correct => initializer is all zeroes ptr is null, length == 0 => initializer is void else => initializer contains non-zero bytes This would allow us to avoid a memset where the data structure is explicitly declared with all void initializers. Where the type is statically known, 'x = T.init' can still be more effective, because the compiler can freely chose how to initialize a data structure, based on whether x is already initialized or not, T.init contains a mix of void and non-void fields or if one or more of the fields are overwritten shortly after. typeid(T).initializer is the more blunt tool. T.init is a compiler intrinsic, typeid(T).initializer is data.
Comment #4 by robert.schadek — 2024-12-13T18:32:32Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18904 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB