Compile-time variables
H. S. Teoh
hsteoh at quickfur.ath.cx
Fri Apr 6 00:21:54 UTC 2018
On Thu, Apr 05, 2018 at 11:53:00PM +0000, Kayomn via Digitalmars-d-learn wrote:
[...]
> -------------------------------------------------------------------------------
> alias NodeTypeID = uint;
>
> enum NodeTypeID getNodeID() {
> static NodeTypeID lastID = 0;
>
> return lastID++;
> }
>
> enum NodeTypeID getNodeID(T)() {
> static NodeTypeID typeID = getNodeID();
>
> return typeID;
> }
> -------------------------------------------------------------------------------
>
> The expectation is that this is executed at compile time,
[...]
> However, I've been struggling with an error pertaining to getNodeType.
> The return statement of lastID++ is flagging the error "Static
> variable cannot be read at compile time."
`lastID`, as declared above, are runtime variables. The 'static' in this
case just means it's thread-local, rather than allocated on the stack.
You cannot modify these variables at compile-time.
> I may just be taking too much of a C++ lens to this, but to me this
> seems like it should work? Am I missing a qualifier or something here?
You appear to be wanting to increment a global variable during
compile-time. Unfortunately, there is no such thing as a compile-time
global variable. You will have to find some other way to implement what
you want.
One way to do this would be to use compile-time introspection to
construct a list of nodes, and then use a CTFE function or static
foreach to generate node IDs all at once. For example:
string generateEnum(T...)()
{
if (__ctfe) { // only run at compile-time
string code = "enum NodeIds {";
foreach (ident; T) {
code ~= ident ~ ", ";
}
code ~= "}";
return code;
}
else assert(0);
}
alias MyNodes = List!(
// Just an example; you probably want to generate this
// list via introspection, e.g. via __traits(getMembers)
// or something like that.
identifier1,
identifier2,
...
);
mixin(generateEnum!MyNodes); // defines `enum NodeIds`
static assert(NodeIds.identifier1 == 0);
static assert(NodeIds.identifier2 == 1);
...
There are probably other ways to do it too, but I chose enum because it
naturally assigns incrementing IDs to its members, so it's a convenient
construct for this purpose.
T
--
Having a smoking section in a restaurant is like having a peeing section in a swimming pool. -- Edward Burr
More information about the Digitalmars-d-learn
mailing list