__traits(compiles, ...) returns true for syntactic garbage and for semantically incorrect code

Pavel proger79 at gmail.com
Mon Dec 17 04:04:29 PST 2012


On Monday, 17 December 2012 at 11:03:01 UTC, Simen Kjaeraas wrote:
> On 2012-42-17 11:12, Pavel <proger79 at 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


More information about the Digitalmars-d mailing list