Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 17, 2012 __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Either I do not understand the work of this feature or it is an obvious bug: import std.stdio; import std.conv; void main() { enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$"; enum bool bTest = __traits(compiles, expr); enum bool bTest2 = __traits(compiles, "int i = q{};"); writeln("bTest: " ~ to!string(bTest)); writeln("bTest2: " ~ to!string(bTest2)); } Produces (tested with dmd32 2.060 and dmd32 2.059): bTest: true bTest2: true (http://dpaste.dzfl.pl/5d338ab3) Could you please somebody explain this? Thanks, Pavel |
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | Argument is supposed to be not a string but plain D code. And it is pretty logical that string literal is a valid compiling D code, as well as an existing variable name.
On Monday, 17 December 2012 at 10:42:38 UTC, Pavel wrote:
> Either I do not understand the work of this feature or it is an obvious bug:
>
> import std.stdio;
> import std.conv;
>
> void main()
> {
> enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
>
> enum bool bTest = __traits(compiles, expr);
> enum bool bTest2 = __traits(compiles, "int i = q{};");
>
> writeln("bTest: " ~ to!string(bTest));
> writeln("bTest2: " ~ to!string(bTest2));
> }
>
> Produces (tested with dmd32 2.060 and dmd32 2.059):
> bTest: true
> bTest2: true
>
> (http://dpaste.dzfl.pl/5d338ab3)
>
> Could you please somebody explain this?
>
> Thanks,
> Pavel
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | On Monday, 17 December 2012 at 10:42:38 UTC, Pavel wrote:
> Either I do not understand the work of this feature or it is an obvious bug:
>
> import std.stdio;
> import std.conv;
>
> void main()
> {
> enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
>
> enum bool bTest = __traits(compiles, expr);
> enum bool bTest2 = __traits(compiles, "int i = q{};");
>
> writeln("bTest: " ~ to!string(bTest));
> writeln("bTest2: " ~ to!string(bTest2));
> }
>
> Produces (tested with dmd32 2.060 and dmd32 2.059):
> bTest: true
> bTest2: true
>
> (http://dpaste.dzfl.pl/5d338ab3)
>
> Could you please somebody explain this?
>
> Thanks,
> Pavel
__traits(compiles, xxx) just verifies that xxx does not resolve to error. In your case, it resolves to... string!
Perhaps you wanted to mixin the string?
//----
import std.stdio;
import std.conv;
void main()
{
enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
enum bool bTest = __traits(compiles, mixin(expr));
enum bool bTest2 = __traits(compiles, mixin("int i = q{};"));
enum bool bTest3 = __traits(compiles, mixin("(int i) => 2*i"));
writeln("bTest: " ~ to!string(bTest));
writeln("bTest2: " ~ to!string(bTest2));
writeln("bTest3: " ~ to!string(bTest3));
}
//----
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | On 2012-42-17 11:12, Pavel <proger79@gmail.com> wrote: > Either I do not understand the work of this feature or it is an obvious bug: > > import std.stdio; > import std.conv; > > void main() > { > enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$"; > > enum bool bTest = __traits(compiles, expr); > enum bool bTest2 = __traits(compiles, "int i = q{};"); > > writeln("bTest: " ~ to!string(bTest)); > writeln("bTest2: " ~ to!string(bTest2)); > } > > Produces (tested with dmd32 2.060 and dmd32 2.059): > bTest: true > bTest2: true > > (http://dpaste.dzfl.pl/5d338ab3) > > Could you please somebody explain this? > > Thanks, > Pavel Let's start off with the obligatory 'You're doing it wrong'. __traits(compiles, ...) does not check the content of strings. If you want that, use mixin("somestring"). What your code does is simply check if the string is one that could be embedded in D code, which both of them can. If instead of using strings you do this: enum bool bTest2 = __traits(compiles, {int i = q{};}); You will see that the result is false. -- Simen |
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to mist | On Monday, 17 December 2012 at 10:59:38 UTC, mist wrote:
> Argument is supposed to be not a string but plain D code. And it is pretty logical that string literal is a valid compiling D code, as well as an existing variable name.
>
> On Monday, 17 December 2012 at 10:42:38 UTC, Pavel wrote:
>> Either I do not understand the work of this feature or it is an obvious bug:
>>
>> import std.stdio;
>> import std.conv;
>>
>> void main()
>> {
>> enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
>>
>> enum bool bTest = __traits(compiles, expr);
>> enum bool bTest2 = __traits(compiles, "int i = q{};");
>>
>> writeln("bTest: " ~ to!string(bTest));
>> writeln("bTest2: " ~ to!string(bTest2));
>> }
>>
>> Produces (tested with dmd32 2.060 and dmd32 2.059):
>> bTest: true
>> bTest2: true
>>
>> (http://dpaste.dzfl.pl/5d338ab3)
>>
>> Could you please somebody explain this?
>>
>> Thanks,
>> Pavel
Thanks for the clarification - now everything is clear!
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Monday, 17 December 2012 at 11:03:01 UTC, Simen Kjaeraas wrote:
> On 2012-42-17 11:12, Pavel <proger79@gmail.com> wrote:
>
>> Either I do not understand the work of this feature or it is an obvious bug:
>>
>> import std.stdio;
>> import std.conv;
>>
>> void main()
>> {
>> enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
>>
>> enum bool bTest = __traits(compiles, expr);
>> enum bool bTest2 = __traits(compiles, "int i = q{};");
>>
>> writeln("bTest: " ~ to!string(bTest));
>> writeln("bTest2: " ~ to!string(bTest2));
>> }
>>
>> Produces (tested with dmd32 2.060 and dmd32 2.059):
>> bTest: true
>> bTest2: true
>>
>> (http://dpaste.dzfl.pl/5d338ab3)
>>
>> Could you please somebody explain this?
>>
>> Thanks,
>> Pavel
>
> Let's start off with the obligatory 'You're doing it wrong'.
>
> __traits(compiles, ...) does not check the content of strings.
> If you want that, use mixin("somestring").
>
> What your code does is simply check if the string is one that
> could be embedded in D code, which both of them can.
>
> If instead of using strings you do this:
>
> enum bool bTest2 = __traits(compiles, {int i = q{};});
>
> You will see that the result is false.
Nice hint with __traits(compiles, { <statements> }) - thanks!
(Because as I've now read in documentation the __traits(compiles) does not accepts statements directly.)
Because when writing templates with operating code as strings it is easy to forget that __traits(compiles, ...) behaves so I suppose it is useful to create a utility template for it:
template Compiles(string code)
{
enum bool Compiles = __traits(compiles, mixin("{" ~ code ~ "}"));
}
void main()
{
enum string code1 = "int i = q{};";
enum string code2 = "int i = 5; i++;";
writeln("Compiles `" ~ code1 ~ "`: " ~ to!string(Compiles!code1));
writeln("Compiles `" ~ code2 ~ "`: " ~ to!string(Compiles!code2));
}
Pavel
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | On Monday, 17 December 2012 at 12:04:30 UTC, Pavel wrote:
> On Monday, 17 December 2012 at 11:03:01 UTC, Simen Kjaeraas wrote:
>> On 2012-42-17 11:12, Pavel <proger79@gmail.com> wrote:
>>
>>> Either I do not understand the work of this feature or it is an obvious bug:
>>>
>>> import std.stdio;
>>> import std.conv;
>>>
>>> void main()
>>> {
>>> enum string expr = "DMD compiles this garbage ... iiiii - \" #### $$$";
>>>
>>> enum bool bTest = __traits(compiles, expr);
>>> enum bool bTest2 = __traits(compiles, "int i = q{};");
>>>
>>> writeln("bTest: " ~ to!string(bTest));
>>> writeln("bTest2: " ~ to!string(bTest2));
>>> }
>>>
>>> Produces (tested with dmd32 2.060 and dmd32 2.059):
>>> bTest: true
>>> bTest2: true
>>>
>>> (http://dpaste.dzfl.pl/5d338ab3)
>>>
>>> Could you please somebody explain this?
>>>
>>> Thanks,
>>> Pavel
>>
>> Let's start off with the obligatory 'You're doing it wrong'.
>>
>> __traits(compiles, ...) does not check the content of strings.
>> If you want that, use mixin("somestring").
>>
>> What your code does is simply check if the string is one that
>> could be embedded in D code, which both of them can.
>>
>> If instead of using strings you do this:
>>
>> enum bool bTest2 = __traits(compiles, {int i = q{};});
>>
>> You will see that the result is false.
>
>
> Nice hint with __traits(compiles, { <statements> }) - thanks!
> (Because as I've now read in documentation the __traits(compiles) does not accepts statements directly.)
>
> Because when writing templates with operating code as strings it is easy to forget that __traits(compiles, ...) behaves so I suppose it is useful to create a utility template for it:
>
> template Compiles(string code)
> {
> enum bool Compiles = __traits(compiles, mixin("{" ~ code ~ "}"));
> }
>
> void main()
> {
> enum string code1 = "int i = q{};";
> enum string code2 = "int i = 5; i++;";
>
> writeln("Compiles `" ~ code1 ~ "`: " ~ to!string(Compiles!code1));
> writeln("Compiles `" ~ code2 ~ "`: " ~ to!string(Compiles!code2));
> }
Oops, bad idea - it will work only for self-contained code but will not work when code references some variables from current scope.
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | On Monday, 17 December 2012 at 12:20:23 UTC, Pavel wrote: > Oops, bad idea - it will work only for self-contained code but will not work when code references some variables from current scope. Template mixin helps to solve the issue, so the utility template can be: mixin template Compiles(string code) { enum bool Result = __traits(compiles, mixin("{" ~ code ~ "}")); } with usage: enum string code1 = "int i = q{};"; int j = 0; enum string code2 = "j++;"; enum string code3 = "void foo(){}"; mixin Compiles!code1 compilesCode1; mixin Compiles!code2 compilesCode2; mixin Compiles!code3 compilesCode3; writeln("Compiles `" ~ code1 ~ "`: " ~ to!string(compilesCode1.Result) ); writeln("Compiles `" ~ code2 ~ "`: " ~ to!string(compilesCode2.Result) ); writeln("Compiles `" ~ code3 ~ "`: " ~ to!string(compilesCode3.Result) ); It seems to me handier to use it from templates manipulating code as strings than usage of __traits(compiles,...) directly. Pavel |
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel | On Monday, 17 December 2012 at 14:15:42 UTC, Pavel wrote:
> It seems to me handier to use it from templates manipulating code as strings than usage of __traits(compiles,...) directly.
I'm not quite sure how this is nicer to use than »enum foo = __traits(compiles, { mixin(bar); });«, but tastes differ…
David
|
December 17, 2012 Re: __traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Monday, 17 December 2012 at 14:18:25 UTC, David Nadlinger wrote:
> On Monday, 17 December 2012 at 14:15:42 UTC, Pavel wrote:
>> It seems to me handier to use it from templates manipulating code as strings than usage of __traits(compiles,...) directly.
>
> I'm not quite sure how this is nicer to use than »enum foo = __traits(compiles, { mixin(bar); });«, but tastes differ…
Yup, it is only IMHO :) Useful for forgetful people as me: because without the utility template it is easy to forget to use 'mixin' and to put the statements in the block.
|
Copyright © 1999-2021 by the D Language Foundation