www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13678] New: TypeInfo.init is inconsistent

https://issues.dlang.org/show_bug.cgi?id=13678

          Issue ID: 13678
           Summary: TypeInfo.init is inconsistent
           Product: D
           Version: D2
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: minor
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: Marco.Leise gmx.de

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.

--
Nov 03 2014