Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 17, 2013 more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
are these bugs or expected behavior? (2 issues, see code below) i thought enums are just compile time copy&paste magic so i cannot think of a reason why it should not be available at compile time... if buggy, what is broken, enum (really bad) or pragma(msg,...) (worse enough)? and are they in bugzilla already? (looked but nothing caught my eye) if expected behavior, can someone pls explain. cheers /det import std.stdio; enum Test{ test2 = 2, test4 = 4 } enum foo = Test.test2; Test bar = Test.test4; pragma( msg, foo ); // why does it print: cast(Test)2 // it should be: test2 // or at least simply: 2 // pragma( msg, bar ); // Error: variable bar cannot be read at compile time void main(){ writeln( typeof(foo).stringof, " = ", foo ); // prints as expected: Test = test2 writeln( typeof(bar).stringof, " = ", bar ); // prints as expected: Test = test4 } |
August 17, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On Saturday, 17 August 2013 at 05:22:53 UTC, captaindet wrote: > are these bugs or expected behavior? (2 issues, see code below) > > i thought enums are just compile time copy&paste magic so i cannot think of a reason why it should not be available at compile time... > > if buggy, what is broken, enum (really bad) or pragma(msg,...) (worse enough)? > and are they in bugzilla already? (looked but nothing caught my eye) > > if expected behavior, can someone pls explain. > > cheers /det > > > import std.stdio; > > enum Test{ > test2 = 2, > test4 = 4 > } > > enum foo = Test.test2; > Test bar = Test.test4; > > pragma( msg, foo ); // why does it print: cast(Test)2 > // it should be: test2 > // or at least simply: 2 > It is 2! Notice the 2 at the end? The cast is just mumbo jumbo due to the the compiler deals with the stuff. You can remove the casts manually if you don't like them. > // pragma( msg, bar ); // Error: variable bar cannot be read at compile time > Because bar is not a compile time constant. It is an runtime object. pragma can't display certain things that it doesn't know about due to the way the compiler works. It's unfortunate in some cases that it simply doesn't work correctly, in others, such as this, it works as expected. You could argue that the compiler should know that bar is known at compile time up to the pragma, and I would agree... but the compiler simply isn't that smart. > void main(){ > writeln( typeof(foo).stringof, " = ", foo ); > // prints as expected: Test = test2 > writeln( typeof(bar).stringof, " = ", bar ); > // prints as expected: Test = test4 > } these print the value at runtime. In this case the compiler is already out of the picture. Basically pragmas are evaluated during compile time, if the compiler can't figure out the value(or is too stupid) then it can't print them and throws an error. In fact, even in CTFE stuff pragma doesn't function like one would hope. This again, is due to the way the compiler works. Just a quirky and unfortunate way that the d compiler works. |
August 17, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | [enum foo = Test.test2;] On 2013-08-17 01:03, JS wrote: >> pragma( msg, foo ); // why does it print: cast(Test)2 >> // it should be: test2 >> // or at least simply: 2 >> > > It is 2! Notice the 2 at the end? The cast is just mumbo jumbo due to > the the compiler deals with the stuff. You can remove the casts > manually if you don't like them. i saw the 2, but foo semantically contains a Test Test.test2 (this is the idea) or technically an int 2. don't understand why pragma displays an explicit cast here. maybe some internals that are leaking through the pragma(msg,...) implementation. >> // pragma( msg, bar ); // Error: variable bar cannot be read at compile time >> > > Because bar is not a compile time constant. It is an runtime object. > pragma can't display certain things that it doesn't know about due to > the way the compiler works. It's unfortunate in some cases that it > simply doesn't work correctly, in others, such as this, it works as > expected. > You could argue that the compiler should know that bar is known at > compile time up to the pragma, and I would agree... but the compiler > simply isn't that smart. but this is my very point! my understanding was that enums are all compile time entities that are just copied around. at compile time. a named enum type should make no difference. where is it documented that named enums become runtime objects? but you are right that this seems to be the case here and that pragma(msg,...) is off the hook this time: enum Test{ test2 = 2, test4 = 4 } enum foo = Test.test2; Test bar = Test.test4; // enum wtf = bar; // Error: variable bar cannot be read at compile time /det |
August 17, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On 2013-08-17 01:51, captaindet wrote:
> named enums become runtime objects
-> named enums become runtime *only* objects
|
August 17, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On 2013-08-17 01:51, captaindet wrote:
> my understanding was that enums are all compile time entities that
> are just copied around. at compile time. a named enum type should
> make no difference.
oh i see now, naming them is just creating a disguise for the base type. then they can become compile-time-known when declared const (see below). only anonymous enum (manifest constant) are true compile time objects. reminds me of my (type)tuple confusion. two completely different animals/concepts, with similar/confusing syntax and blurry docs.
module demo;
import std.stdio;
enum Test{
test2 = 2,
test4 = 4
}
enum foo = Test.test2;
const Test bar = Test.test4; // does the trick
enum wtf = bar;
pragma( msg, foo ); // prints: cast(Test)2
pragma( msg, bar ); // pritns: cast(Test)4
void main(){
writeln( typeof(foo).stringof, " = ", foo ); // prints: Test = test2
writeln( typeof(bar).stringof, " = ", bar ); // prints: const(Test) = test4
}
|
August 17, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On Saturday, 17 August 2013 at 05:22:53 UTC, captaindet wrote: > import std.stdio; > > enum Test{ > test2 = 2, > test4 = 4 > } Enumeration. > enum foo = Test.test2; Manifest Const > Test bar = Test.test4; Runtime variable. Enum is being abused. In the first case you are declaring an enumeration[1], these values are known at compile time. Second you defined a manifest constant, this is what you would see from #define in C. The symbol, foo, is replaced by the right hand side when referenced. Third you've declared a variable, bar, which will store your enumerated value, 4. Variables are not compile time, even if the value stored came from a compile time known value. int foobar = 5; // 5 is known at compile time, foobar is not. > pragma( msg, foo ); // why does it print: cast(Test)2 You are referring to a manifest constant, this is a simple textual replacement. Enumerations are typed, 2 is not a Test, so the compiler will write out a cast so the type system is happy. Similarly Test.test2 is not the value of foo, foo is a signal to the compiler to insert "cast(Test)2." Hope that makes sense. 1. http://en.wikipedia.org/wiki/Enumeration |
August 18, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | On 2013-08-17 14:36, Jesse Phillips wrote: > Third you've declared a variable, bar, which will store your > enumerated value, 4. Variables are not compile time, even if the > value stored came from a compile time known value. yep, it completely escaped me that these are 'normal' variables. and i have realized now that i can make them known at compile time the same way as is done for other 'normal' variables, by declaring them const ;) >> pragma( msg, foo ); // why does it print: cast(Test)2 > > You are referring to a manifest constant, this is a simple textual > replacement. Enumerations are typed, 2 is not a Test, so the compiler > will write out a cast so the type system is happy. Similarly > Test.test2 is not the value of foo, foo is a signal to the compiler > to insert "cast(Test)2." > > Hope that makes sense. things are becoming clearer now. thanks for your explanation, jesse! /det |
August 18, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On Sunday, 18 August 2013 at 00:17:22 UTC, captaindet wrote:
> On 2013-08-17 14:36, Jesse Phillips wrote:
>> Third you've declared a variable, bar, which will store your
>> enumerated value, 4. Variables are not compile time, even if the
>> value stored came from a compile time known value.
>
> yep, it completely escaped me that these are 'normal' variables. and i have realized now that i can make them known at compile time the same way as is done for other 'normal' variables, by declaring them const ;)
>
But if they are const then what good does that do you? Just use an alias or enum in the first place?
|
August 19, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On 2013-08-17 21:54, JS wrote:
> On Sunday, 18 August 2013 at 00:17:22 UTC, captaindet wrote:
>> On 2013-08-17 14:36, Jesse Phillips wrote:
>>> Third you've declared a variable, bar, which will store your
>>> enumerated value, 4. Variables are not compile time, even if the
>>> value stored came from a compile time known value.
>>
>> yep, it completely escaped me that these are 'normal' variables.
>> and i have realized now that i can make them known at compile time
>> the same way as is done for other 'normal' variables, by declaring
>> them const ;)
>>
>
> But if they are const then what good does that do you? Just use an
> alias or enum in the first place?
to be honest, i have not found a use case ;)
highest priority was that i understood what was going on here...
how did i get there? i was looking for an easy way to get pragma(msg,...) to print the given name for an enumerated value. in this example test2 or test4 instead of 2 and 4 - just like write is doing it at runtime. so i was playing around with the different variants of enum to see if i could get it working somehow.. and got sidetracked....
in the end i stuck to manifest constant enums storing the enumerated values and found that
pragma( msg, to!string(foo) );
is doing the trick.
/det
|
August 19, 2013 Re: more enum and pragma troubles | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On Monday, 19 August 2013 at 04:37:58 UTC, captaindet wrote:
> On 2013-08-17 21:54, JS wrote:
>> On Sunday, 18 August 2013 at 00:17:22 UTC, captaindet wrote:
>>> On 2013-08-17 14:36, Jesse Phillips wrote:
>>>> Third you've declared a variable, bar, which will store your
>>>> enumerated value, 4. Variables are not compile time, even if the
>>>> value stored came from a compile time known value.
>>>
>>> yep, it completely escaped me that these are 'normal' variables.
>>> and i have realized now that i can make them known at compile time
>>> the same way as is done for other 'normal' variables, by declaring
>>> them const ;)
>>>
>>
>> But if they are const then what good does that do you? Just use an
>> alias or enum in the first place?
>
> to be honest, i have not found a use case ;)
>
> highest priority was that i understood what was going on here...
>
> how did i get there? i was looking for an easy way to get pragma(msg,...) to print the given name for an enumerated value. in this example test2 or test4 instead of 2 and 4 - just like write is doing it at runtime. so i was playing around with the different variants of enum to see if i could get it working somehow.. and got sidetracked....
>
> in the end i stuck to manifest constant enums storing the enumerated values and found that
>
> pragma( msg, to!string(foo) );
>
> is doing the trick.
>
>
> /det
I had the same issues, it is not an issue with logic but with the weird way dmd works(pragma is handled very early on and before ctfe's are completely parsed).
Remember you can use ctfe's to format strings any way you want and even do logic and other stuff but you can't use pragma's inside the ctfe on ctfe variables(because as far as pragma is concerned, they are run time at that point).
module main;
import std.stdio, std.conv;
template foo(alias T)
{
string foo(string s)
{
string x = to!string(T) ~ s ~ "yyyy";
//pragma(msg, x); // pragma see's x as a run time variable(or rather pragma is executed before x is truly defined)
return x;
}
}
int main(string[] argv)
{
pragma(msg, foo!("asf")("xxx")); // note, it prints what the commented pragma is suppose to print, but this one works!!! Because it is outside the ctfe and foo!(...) can be computed at compile time
readln();
return 0;
}
I really believe the issue is with the compiler and is a bug. Somehow x gets marked as run time, probably because ctfe's are suppose to work at run time too... even though in this instance it is being used at compile time. (so it should work)
|
Copyright © 1999-2021 by the D Language Foundation