www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Possible UDA bug

reply "jerro" <a a.com> writes:
This code currently compiles:

int bar();
 bar() void foo(){}

But this gives an error, as expected:

int bar();
 bar() void foo(){}
pragma(msg, __traits(getAttributes, foo));

I would expect the first example to give an error too. Is the 
current behavior deliberate or is it a DMD bug?
Feb 24 2013
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Sunday, 24 February 2013 at 16:04:19 UTC, jerro wrote:
 This code currently compiles:

 int bar();
  bar() void foo(){}

 But this gives an error, as expected:

 int bar();
  bar() void foo(){}
 pragma(msg, __traits(getAttributes, foo));

 I would expect the first example to give an error too. Is the 
 current behavior deliberate or is it a DMD bug?

Why the fist is wrong? It is a call expression which is acceptable according to the UDA grammar. The reason the second does not compile is because the statement is evaluated at CT, and interpreter cannot evaluate call without source, like a regular explicit call.
Feb 24 2013
prev sibling next sibling parent "jerro" <a a.com> writes:
 Why the fist is wrong? It is a call expression which is
 acceptable according to the UDA grammar.

I'm not saying the syntax in the first example is, or should be, invalid.
 The reason the second
 does not compile is because the statement is evaluated at CT, 
 and
 interpreter cannot evaluate call without source, like a regular
 explicit call.

I know that, the thing is that it will give this error every time you try to use the attributes of foo (or am I missing some use case?). So I think it would be better if the declaration in the first example would be illegal, since it doesn't really make any sense and is useless.
Feb 24 2013
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Sunday, 24 February 2013 at 16:36:05 UTC, jerro wrote:
 The reason the second
 does not compile is because the statement is evaluated at CT, 
 and
 interpreter cannot evaluate call without source, like a regular
 explicit call.

I know that, the thing is that it will give this error every time you try to use the attributes of foo (or am I missing some use case?). So I think it would be better if the declaration in the first example would be illegal, since it doesn't really make any sense and is useless.

No. extern(C) int bar(); bar() void foo(){} //pragma(msg, __traits(getAttributes, foo)); void main() { auto x = __traits(getAttributes, foo)[0]; } is compilable and runnable when linker knows where bar() is.
Feb 24 2013
prev sibling next sibling parent "jerro" <a a.com> writes:
 extern(C) int bar();
  bar() void foo(){}
 //pragma(msg, __traits(getAttributes, foo));

 void main()
 {
     auto x = __traits(getAttributes, foo)[0];
 }

 is compilable and runnable when linker knows where bar() is.

So this is actually supposed to work? The documentation says:
 User Defined Attributes (UDA) are compile time expressions that 
 can be attached to a declaration.

I guess the documentation is wrong or at least unclear in that case.
Feb 24 2013
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 24 Feb 2013 13:03:26 -0500, jerro <a a.com> wrote:

 extern(C) int bar();
  bar() void foo(){}
 //pragma(msg, __traits(getAttributes, foo));

 void main()
 {
     auto x = __traits(getAttributes, foo)[0];
 }

 is compilable and runnable when linker knows where bar() is.

So this is actually supposed to work? The documentation says:
 User Defined Attributes (UDA) are compile time expressions that can be  
 attached to a declaration.

I guess the documentation is wrong or at least unclear in that case.

It sort of makes sense. Remember, these are compile-time entities. If nobody every looks at them, there is no need for the compiler to either. For example, this compiles: template foo(T) { enum foo = new T; } But if you ever try to use it, the compiler will complain. -Steve
Feb 24 2013
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Sunday, 24 February 2013 at 18:03:29 UTC, jerro wrote:
 extern(C) int bar();
  bar() void foo(){}
 //pragma(msg, __traits(getAttributes, foo));

 void main()
 {
    auto x = __traits(getAttributes, foo)[0];
 }

 is compilable and runnable when linker knows where bar() is.

So this is actually supposed to work? The documentation says:
 User Defined Attributes (UDA) are compile time expressions 
 that can be attached to a declaration.

I guess the documentation is wrong or at least unclear in that case.

No, you are misunderstanding the spec. __traits(getAttributes, foo) is CT expression. The reason why it does not work in your example is because you deliberately placed sourceless function which is required for evaluation. Your case is close to: int foo(); int bar() { return foo(); } enum x = bar(); void main(){} So, there is nothing wrong with calling CTFE function from other. The (deliberately created) problems arise when function is sourceless.
Feb 24 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/24/2013 05:04 PM, jerro wrote:
 This code currently compiles:

 int bar();
  bar() void foo(){}

 But this gives an error, as expected:

 int bar();
  bar() void foo(){}
 pragma(msg, __traits(getAttributes, foo));

 I would expect the first example to give an error too. Is the current
 behavior deliberate or is it a DMD bug?

Bug.
Feb 24 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 02/24/2013 08:19 PM, Timon Gehr wrote:
 On 02/24/2013 05:04 PM, jerro wrote:
 This code currently compiles:

 int bar();
  bar() void foo(){}

 But this gives an error, as expected:

 int bar();
  bar() void foo(){}
 pragma(msg, __traits(getAttributes, foo));

 I would expect the first example to give an error too. Is the current
 behavior deliberate or is it a DMD bug?

Bug.

Actually the documentation does not treat this at all. However, it is not the behaviour discussed on the newsgroup. Note that it introduces a funny little macro system into the language. Eg. this: import std.stdio; int x; (write(x++),writeln()) void foo(){} void main(){ __traits(getAttributes, foo); __traits(getAttributes, foo)[0]; __traits(getAttributes, foo)[0]; } Outputs: 0 12
Feb 24 2013