www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3952] New: pragma(msg,...) has bugs + alternative idea

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3952

           Summary: pragma(msg,...) has bugs + alternative idea
           Product: D
           Version: 2.041
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc


--- Comment #0 from bearophile_hugs eml.cc 2010-03-13 05:11:28 PST ---
The D2 docs state about pragma(msg, ...):
Prints a message while compiling, the AssignExpressions must be string
literals:
pragma(msg, "compiling...");

I think that means it must accept string literals only, and produce a syntax
error in all the other cases. In practice if you look at the following program
the pragma(msg, foo0()); prints the "this is a test" string. This is useful,
but in many other cases this doesn't work or works in strange ways:


string foo0() {
    return "this is a test";
}
string foo1() {
    return "";
}
string foo2() {
    string result;
    return result;
}
string foo3() {
    return [];
}
pragma(msg, foo0());
pragma(msg, foo1());
pragma(msg, foo2());
pragma(msg, foo3());
string hello = "red";
pragma(msg, hello);
pragma(msg, 12);
void main() {}



The compile-timeoutput of that program is:
this is a test

null
[]
hello
12


So I think pragma(msg,...) needs some debugging.

-------------

This program doesn't compile:


enum int x = 10;
static if (x)
    pragma(msg, "true");
else
    pragma(msg, "false");
void main() {}



It prints the error:
test.d(4): Declaration expected, not 'else'

I can understand the cause of that error, but to improve the usefulness of the
pragma and avoid errors like that one I think the compiler can rewrite the
pragma(msg, ...) as:

{pragma(msg, ...);}

-------------

To increase the usefulness of the pragma(msg, ...) I suggest to not let it
print a newline after the string.

-------------

D2 programs have a better and better CTFE, so the need for good enough printing
is growing.

So I suggest to add a simple printing function that works in the same way both
at compile-time in CTFE and at runtime. To keep things simple it can just print
a string (literal or inside a variable) and it does NOT print a newline.

It can be used in a loop too, in CTFE too, to print many things (so it's
different from a pragma(msg,...):

string foo(int i) {
    foreach (i, 0 .. 10)
        ctputs(ToString!(i));
}

Note that it's a true function, so there is no need for {}.

"ctputs" is just one of the possible names of this function.

Once such function is present, the pragma(msg,...) can probably be removed from
the language.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 13 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3952



--- Comment #1 from bearophile_hugs eml.cc 2010-08-06 09:34:59 PDT ---
In D1 there were no template constraints, so to test the template arguments I
used to add some static asserts inside them. So a wrong template argument shows
a error message written by me that explains why the instantiation has failed
(unfortunately those error messages show the line number inside the template).

When a template constraint is composed of some different parts in &&, it's less
easy to understand what condition has failed, so I miss the error messages
written by me. This is an example (that probably I will simplify), there are
four conditions, and for a person that has not written this code, and is just
using Phobos, it's not immediately obvious what part has failed:


auto opBinary(string op, TOther)(TOther other)
  if (op == "~" && is(TOther == struct) &&
      (!__traits(compiles, { void isTuple(U...)(Tuple!U){} isTuple(other); })
||
       distinctFieldNames!(T, TOther.TypesAndStrings)() )) { ...


There is a simple solution. The simple template constraints often don't need
extra error messages, so they can be left as they are now.

Putting one or more error message inside a template constraints turns them into
messy code, so in such cases it's better to move the tests elsewhere, in an
external template/CTFE:

template IsGoodFoo(T) {
    static if (...) {
        enum bool IsGoodFoo = true;
    } else {
        ctputs("this is an error message");
        return false;
    }
}

void foo(T)(T x) if (IsGoodFoo!T) { ...


So the ctputs() is usable for the template constraints error messages too.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 06 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3952



--- Comment #2 from bearophile_hugs eml.cc 2010-08-07 00:14:07 PDT ---
Andrei has asked if just a pragma(msg) is enough for the error template
constraints.

In some situations it works. But to use pragma(msg) you have to guard it with a
static if. So if the template constraint is a CTFE (that uses a normal 'if'
instead of a 'static if') you can't use it. While ctputs() can be used, this
shows the error message even if it's not required:

bool isGoodFoo(int x) {
    if (x > 10) {
        return true;
    } else {
        pragma(msg, "no good");
        // ctputs("no good");
        return false;
    }
}
void foo(int N)() if (isGoodFoo(N)) {
}
void main() {
    foo!(20)();
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 07 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3952


BCS <shro8822 vandals.uidaho.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |shro8822 vandals.uidaho.edu


--- Comment #3 from BCS <shro8822 vandals.uidaho.edu> 2010-08-08 07:23:18 PDT
---
What about this case:

auto Fn(T...)(T t)
{
  foreach(Te; T) // compile time foreach
  {
    pragam(msg, "processing: " ~ Te.stringof)
    ... ctfe valid code
  }
}

void main()
{
   Fn!(int, int, float)(1,2,3.14); // will be evaluated at _run time_
}

//
 expected CT output:

processing: int
processing: int
processing: float

//
 expected runtime output: none

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 08 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3952



--- Comment #4 from bearophile_hugs eml.cc 2010-08-08 08:17:34 PDT ---
I don't understand what you exactly mean, but similar problems can be solved
by:

if (__ctfe) ctputs("...");

Or:
if (!__ctfe) ctputs("...");

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 08 2010