www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static if - unexpected results

reply DLearner <bmqazwsx123 gmail.com> writes:
Hi

Was looking for compile-time detection of a struct variable.
However, the following test code gave the two 'FAILS' shown below.
Comments?
```
void main() {
    import std.stdio : writeln;
    import std.traits;

    string mxnTst(string VarName) {
       return

       `static if (is(typeof(` ~ VarName ~ `) == char)) {` ~
          `writeln("` ~ VarName ~ ` ", " is a char");` ~
       `} else static if (__traits(isPOD, typeof(` ~ VarName ~ 
`))) {` ~
          `writeln("` ~ VarName ~ ` ", " is a struct");` ~
       `} else static if (is(typeof(` ~ VarName ~ `) == int)) {` ~
          `writeln("` ~ VarName ~ ` ", " is an int");` ~
       `} else {` ~
          `static assert(false, "mxnTst Variable '` ~ VarName  ~ 
`' is of unknown type");` ~
       `}`
        ;
    }

    char char1;
    int  int1;
    byte byte1;

    struct foo {
       int  fooint;
       char foochar;
    }
    foo foovar1;

    mixin(mxnTst("char1"));   // Expected: char1 is a char. 
Actual: char1 is a char. (ok)
    mixin(mxnTst("int1"));    // Expected: int1 is an int.  
Actual: int1 is a struct. (FAIL)
    mixin(mxnTst("foovar1")); // Expected: foovar1 is a struct.  
Actual: foovar1 is a struct. (ok)
    mixin(mxnTst("byte1"));   // Expected: Run to fail with the 
static assert message. Actual: byte1 is a struct. (FAIL)
}
```
Jun 23 2023
next sibling parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote:
 Hi

 Was looking for compile-time detection of a struct variable.
 However, the following test code gave the two 'FAILS' shown 
 below.
 Comments?
 ```
 void main() {
    import std.stdio : writeln;
    import std.traits;

    string mxnTst(string VarName) {
       return

       `static if (is(typeof(` ~ VarName ~ `) == char)) {` ~
          `writeln("` ~ VarName ~ ` ", " is a char");` ~
       `} else static if (__traits(isPOD, typeof(` ~ VarName ~ 
 `))) {` ~
          `writeln("` ~ VarName ~ ` ", " is a struct");` ~
       `} else static if (is(typeof(` ~ VarName ~ `) == int)) {` 
 ~
          `writeln("` ~ VarName ~ ` ", " is an int");` ~
       `} else {` ~
          `static assert(false, "mxnTst Variable '` ~ VarName  ~ 
 `' is of unknown type");` ~
       `}`
        ;
    }

    char char1;
    int  int1;
    byte byte1;

    struct foo {
       int  fooint;
       char foochar;
    }
    foo foovar1;

    mixin(mxnTst("char1"));   // Expected: char1 is a char. 
 Actual: char1 is a char. (ok)
    mixin(mxnTst("int1"));    // Expected: int1 is an int.  
 Actual: int1 is a struct. (FAIL)
    mixin(mxnTst("foovar1")); // Expected: foovar1 is a struct.  
 Actual: foovar1 is a struct. (ok)
    mixin(mxnTst("byte1"));   // Expected: Run to fail with the 
 static assert message. Actual: byte1 is a struct. (FAIL)
 }
 ```
``` static assert(__traits(isPOD, int)); // ok. static assert(__traits(isPOD, byte)); // ok. ``` It's a bug in either the spec or the compiler.
Jun 23 2023
next sibling parent reply DLearner <bmqazwsx123 gmail.com> writes:
On Friday, 23 June 2023 at 14:31:45 UTC, FeepingCreature wrote:
 On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote:
[...]
 ```
 static assert(__traits(isPOD, int)); // ok.
 static assert(__traits(isPOD, byte)); // ok.
 ```
 It's a bug in either the spec or the compiler.
I am using ``` DMD64 D Compiler v2.103.0-dirty ``` under ``` Windows [Version 10.0.19045.3086] ``` Do I need to report this anywhere?
Jun 23 2023
parent reply H. S. Teoh <hsteoh qfbox.info> writes:
On Friday, 23 June 2023 at 15:22:36 UTC, DLearner wrote:
 On Friday, 23 June 2023 at 14:31:45 UTC, FeepingCreature wrote:
 On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote:
[...]
 ```
 static assert(__traits(isPOD, int)); // ok.
 static assert(__traits(isPOD, byte)); // ok.
 ```
 It's a bug in either the spec or the compiler.
I am using ``` DMD64 D Compiler v2.103.0-dirty ``` under ``` Windows [Version 10.0.19045.3086] ``` Do I need to report this anywhere?
Tested your original code on latest dmd git master, here's the output: ````d char1 is a char int1 is a struct foovar1 is a struct byte1 is a struct ```` Looks like there isn't a problem? Or at least, it's now fixed in git master. Which exact version of dmd are you using? Did you download from dlang.org or did you build your own? --T
Jun 23 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
On Friday, 23 June 2023 at 15:48:44 UTC, H. S. Teoh wrote:
 On Friday, 23 June 2023 at 15:22:36 UTC, DLearner wrote:
 On Friday, 23 June 2023 at 14:31:45 UTC, FeepingCreature wrote:
 On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote:
[...]
 ```
 static assert(__traits(isPOD, int)); // ok.
 static assert(__traits(isPOD, byte)); // ok.
 ```
 It's a bug in either the spec or the compiler.
I am using ``` DMD64 D Compiler v2.103.0-dirty ``` under ``` Windows [Version 10.0.19045.3086] ``` Do I need to report this anywhere?
Tested your original code on latest dmd git master, here's the output: ````d char1 is a char int1 is a struct foovar1 is a struct byte1 is a struct ```` Looks like there isn't a problem? Or at least, it's now fixed in git master. Which exact version of dmd are you using? Did you download from dlang.org or did you build your own? --T
Probably I misunderstand, but to me: ``` int1 is a struct ``` and ``` byte1 is a struct ``` are both errors. The 'struct' test is being triggered for things that are not structs.
Jun 23 2023
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/23/23 10:31 AM, FeepingCreature wrote:
 On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote:
 Hi

 Was looking for compile-time detection of a struct variable.
 However, the following test code gave the two 'FAILS' shown below.
 Comments?
 ```
 void main() {
    import std.stdio : writeln;
    import std.traits;

    string mxnTst(string VarName) {
       return

       `static if (is(typeof(` ~ VarName ~ `) == char)) {` ~
          `writeln("` ~ VarName ~ ` ", " is a char");` ~
       `} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~
          `writeln("` ~ VarName ~ ` ", " is a struct");` ~
       `} else static if (is(typeof(` ~ VarName ~ `) == int)) {` ~
          `writeln("` ~ VarName ~ ` ", " is an int");` ~
       `} else {` ~
          `static assert(false, "mxnTst Variable '` ~ VarName  ~ `' is 
 of unknown type");` ~
       `}`
        ;
    }

    char char1;
    int  int1;
    byte byte1;

    struct foo {
       int  fooint;
       char foochar;
    }
    foo foovar1;

    mixin(mxnTst("char1"));   // Expected: char1 is a char. Actual: 
 char1 is a char. (ok)
    mixin(mxnTst("int1"));    // Expected: int1 is an int. Actual: int1 
 is a struct. (FAIL)
    mixin(mxnTst("foovar1")); // Expected: foovar1 is a struct. Actual: 
 foovar1 is a struct. (ok)
    mixin(mxnTst("byte1"));   // Expected: Run to fail with the static 
 assert message. Actual: byte1 is a struct. (FAIL)
 }
 ```
``` static assert(__traits(isPOD, int)); // ok. static assert(__traits(isPOD, byte)); // ok. ``` It's a bug in either the spec or the compiler.
It should be a spec change. Change POD to say "type" instead of "struct". The goal of `isPOD` is to determine how careful generic code needs to be to pass the type around, or copy it. Changing it to false implies that it is not "plain old data". I.e. it has a destructor, it has hidden members, or it cannot be copied via bit copying (all of these do not fit the type in question). The only other option is to error on calling `__traits(isPOD, char)`, but I think that's even worse. -Steve
Jun 23 2023
parent FeepingCreature <feepingcreature gmail.com> writes:
On Friday, 23 June 2023 at 18:43:06 UTC, Steven Schveighoffer 
wrote:
 It should be a spec change. Change POD to say "type" instead of 
 "struct".

 The goal of `isPOD` is to determine how careful generic code 
 needs to be to pass the type around, or copy it. Changing it to 
 false implies that it is not "plain old data". I.e. it has a 
 destructor, it has hidden members, or it cannot be copied via 
 bit copying (all of these do not fit the type in question).

 The only other option is to error on calling `__traits(isPOD, 
 char)`, but I think that's even worse.

 -Steve
Yeah, I think that's also where I'm standing. The current behavior seems correct and useful, it's just not documented correctly.
Jun 23 2023
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 6/23/23 07:22, DLearner wrote:

        `} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~
Regardless, you can also use the 'is' expression with the 'struct' keyword. If T is a struct, is (T == struct) that will produce true at compile time. Ali
Jun 23 2023
parent DLearner <bmqazwsx123 gmail.com> writes:
On Friday, 23 June 2023 at 16:51:16 UTC, Ali Çehreli wrote:
 On 6/23/23 07:22, DLearner wrote:

        `} else static if (__traits(isPOD, typeof(` ~ VarName
~ `))) {` ~ Regardless, you can also use the 'is' expression with the 'struct' keyword. If T is a struct, is (T == struct) that will produce true at compile time. Ali
Thanks for this - I can confirm it works.
Jun 23 2023