digitalmars.D - Checking if a type is void
- Stefan Koch (21/21) May 28 2022 Good Day everyone, I know it has been a while since I last posted
- Paul Backus (8/11) May 28 2022 Reminds me of this example someone posted in the community
- Stefan Koch (3/14) May 28 2022 At first I didn't see what was unexpected about that. :)
- Stefan Koch (11/20) May 28 2022 Yes indeed!
- Paul Backus (10/21) May 28 2022 Interestingly, there are some operators that cause the compiler
- Stefan Koch (4/13) May 28 2022 It open up the question of whether it should actually be an error.
- Paul Backus (22/26) May 28 2022 It should be an error because the compilier is lying to you that
- Nick Treleaven (11/12) May 29 2022 I'm going to go off on a tangent just to vent:
- Boris Carvajal (15/27) May 29 2022 There was some code depending on this behavior that I even had to
- Boris Carvajal (6/14) May 29 2022 Not working:
Good Day everyone, I know it has been a while since I last posted on here. Did you know that you could check if a type is void without having to mention the type void? And you do it like this ```D template isVoid(alias X) { enum bool isVoid = is(mixin(`!X`)); } pragma(msg, isVoid!(int)); ``` Check it out for yourself ;) The reason this is that internally a TypeExpression is created and all Expressions defined a `!` operation. Because all of them are values/ do have init-expressions. Except for the one type that doesn't which is void. Which is why you cannot create an init expression for void, and that makes the expression `!void` fail during the semantic checks. Cheers, Stefan
May 28 2022
On Saturday, 28 May 2022 at 14:20:22 UTC, Stefan Koch wrote:The reason this is that internally a TypeExpression is created and all Expressions defined a `!` operation. Because all of them are values/ do have init-expressions.Reminds me of this example someone posted in the community Discord a while ago: ```d alias T = int*; alias U = typeof(*T); static assert(is(U == int)); ```
May 28 2022
On Saturday, 28 May 2022 at 14:25:57 UTC, Paul Backus wrote:On Saturday, 28 May 2022 at 14:20:22 UTC, Stefan Koch wrote:At first I didn't see what was unexpected about that. :) But yes that seems to have a similar cause.The reason this is that internally a TypeExpression is created and all Expressions defined a `!` operation. Because all of them are values/ do have init-expressions.Reminds me of this example someone posted in the community Discord a while ago: ```d alias T = int*; alias U = typeof(*T); static assert(is(U == int)); ```
May 28 2022
On Saturday, 28 May 2022 at 14:35:03 UTC, Stefan Koch wrote:On Saturday, 28 May 2022 at 14:25:57 UTC, Paul Backus wrote:Yes indeed! If you try ```d alias T = void*; alias U = typeof(*T); static assert(is(U == void)); ``` You will the the compiler complaining about void having no value, which indicates that the initValue is indeed the mechanism of operation here.```d alias T = int*; alias U = typeof(*T); static assert(is(U == int)); ```At first I didn't see what was unexpected about that. :) But yes that seems to have a similar cause.
May 28 2022
On Saturday, 28 May 2022 at 14:37:42 UTC, Stefan Koch wrote:Yes indeed! If you try ```d alias T = void*; alias U = typeof(*T); static assert(is(U == void)); ``` You will the the compiler complaining about void having no value, which indicates that the initValue is indeed the mechanism of operation here.Interestingly, there are some operators that cause the compiler to catch the error: ```d alias T = int*; alias U = typeof(T[0 .. 0]); // Error: cannot slice type `int*` ``` So I guess this is just a case of missing checks in the semantic analysis of certain kinds of expressions.
May 28 2022
On Saturday, 28 May 2022 at 14:43:13 UTC, Paul Backus wrote:Interestingly, there are some operators that cause the compiler to catch the error: ```d alias T = int*; alias U = typeof(T[0 .. 0]); // Error: cannot slice type `int*` ``` So I guess this is just a case of missing checks in the semantic analysis of certain kinds of expressions.It open up the question of whether it should actually be an error. Having every time which is not `void` or `typeof(assert(0))` to evaluate to a false boolean doesn't seem to be too bad to me.
May 28 2022
On Saturday, 28 May 2022 at 14:47:00 UTC, Stefan Koch wrote:It open up the question of whether it should actually be an error. Having every time which is not `void` or `typeof(assert(0))` to evaluate to a false boolean doesn't seem to be too bad to me.It should be an error because the compilier is lying to you that (e.g.) `*T` is a valid expression, when it really isn't. For example, you may write code like the following: ```d void doSomethingWith(int n) {} void example(alias foo)() { static if (is(typeof(*foo) == int)) doSomethingWith(*foo); } void main() { example!(int*)(); } ``` Due to the behavior discussed in this thread, the `static if` condition evaluates to `true`, but compilation fails on the following line: ``` Error: type `int*` is not an expression ```
May 28 2022
On Saturday, 28 May 2022 at 14:37:42 UTC, Stefan Koch wrote:static assert(is(U == void));I'm going to go off on a tangent just to vent: Seeing `typeof(x) == void` doesn't even mean x is a (runtime) expression, because x can be a template: template t {} static assert(is(typeof(t) == void)); This was only recently documented in February. Apparently Walter and Andrei had previously said it should be removed: https://issues.dlang.org/show_bug.cgi?id=15437#c6 https://github.com/dlang/dlang.org/pull/3218 I don't think it makes any sense.
May 29 2022
On Sunday, 29 May 2022 at 13:26:55 UTC, Nick Treleaven wrote:On Saturday, 28 May 2022 at 14:37:42 UTC, Stefan Koch wrote:There was some code depending on this behavior that I even had to make `typeof(T.t) == void` for consistency https://github.com/dlang/dmd/pull/12294). Quoting myself from https://github.com/dlang/dmd/pull/12897#issuecomment-883798530) ``` there is an overuse of `void` in the compiler internals, there are many objects whose type is `void` when it could be something else like an `unresolved` or `none` type, having this distinction should help in general. ``` I agree it should be changed, now there are many `traits` to replace its usage. We only need a deprecation period.static assert(is(U == void));I'm going to go off on a tangent just to vent: Seeing `typeof(x) == void` doesn't even mean x is a (runtime) expression, because x can be a template: template t {} static assert(is(typeof(t) == void)); This was only recently documented in February. Apparently Walter and Andrei had previously said it should be removed: https://issues.dlang.org/show_bug.cgi?id=15437#c6 https://github.com/dlang/dlang.org/pull/3218 I don't think it makes any sense.
May 29 2022
On Saturday, 28 May 2022 at 14:20:22 UTC, Stefan Koch wrote:```D template isVoid(alias X) { enum bool isVoid = is(mixin(`!X`)); } pragma(msg, isVoid!(int)); ``` Check it out for yourself ;)Not working: ```D pragma(msg, isVoid!(void)); ``` prints 'false'.
May 29 2022