digitalmars.D - __traits(compiles, ...) returns true for syntactic garbage and for
- Pavel (22/22) Dec 17 2012 Either I do not understand the work of this feature or it is an
- mist (4/26) Dec 17 2012 Argument is supposed to be not a string but plain D code. And it
- Pavel (2/34) Dec 17 2012 Thanks for the clarification - now everything is clear!
- monarch_dodra (21/43) Dec 17 2012 __traits(compiles, xxx) just verifies that xxx does not resolve
- Simen Kjaeraas (11/33) Dec 17 2012 Let's start off with the obligatory 'You're doing it wrong'.
-
Pavel
(23/60)
Dec 17 2012
Nice hint with __traits(compiles, {
}) - thanks! - Pavel (4/71) Dec 17 2012 Oops, bad idea - it will work only for self-contained code but
- Pavel (26/29) Dec 17 2012 Template mixin helps to solve the issue, so the utility template
- David Nadlinger (4/6) Dec 17 2012 I'm not quite sure how this is nicer to use than »enum foo =
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
Dec 17 2012
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
Dec 17 2012
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:Thanks for the clarification - now everything is clear!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
Dec 17 2012
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)); } //----
Dec 17 2012
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 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, PavelLet'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
Dec 17 2012
On Monday, 17 December 2012 at 11:03:01 UTC, Simen Kjaeraas wrote:On 2012-42-17 11:12, Pavel <proger79 gmail.com> wrote: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)); } PavelEither 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, PavelLet'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.
Dec 17 2012
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:Oops, bad idea - it will work only for self-contained code but will not work when code references some variables from current scope.On 2012-42-17 11:12, Pavel <proger79 gmail.com> wrote: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)); }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, PavelLet'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.
Dec 17 2012
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
Dec 17 2012
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
Dec 17 2012
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: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.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…
Dec 17 2012
On Monday, 17 December 2012 at 14:29:49 UTC, Pavel wrote: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.Corrected template to work with expressions too: mixin template Compiles(string code) { enum bool Result = __traits(compiles, mixin(code)) || __traits(compiles, mixin("{" ~ code ~ "}")); }
Dec 17 2012