www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Should pure nothrow ---> pure nothrow ?

reply Don <nospam nospam.com> writes:
It seems that pure and nothrow are attributes, just like  safe.
(By contrast, you can overload functions based on const and immutable).
Should the names be changed?
Nov 26 2009
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 27 Nov 2009 03:18:05 +0300, Don <nospam nospam.com> wrote:

 It seems that pure and nothrow are attributes, just like  safe.
 (By contrast, you can overload functions based on const and immutable).
 Should the names be changed?

I agree. I also believe there should be naked (it's somewhat unintuitive that asm { naked; } anywhere withing function body makes it naked).
Nov 26 2009
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Denis Koroskin wrote:
 On Fri, 27 Nov 2009 03:18:05 +0300, Don <nospam nospam.com> wrote:
 
 It seems that pure and nothrow are attributes, just like  safe.
 (By contrast, you can overload functions based on const and immutable).
 Should the names be changed?

I agree. I also believe there should be naked (it's somewhat unintuitive that asm { naked; } anywhere withing function body makes it naked).

Naked is not an externally visible attribute of a function, signature or type, it only concerns the internals. Therefore, it shouldn't be an attribute.
Nov 26 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 Naked is not an externally visible attribute of a function, signature or 
   type, it only concerns the internals. Therefore, it shouldn't be an 
 attribute.

On the other hand I agree with them that currently "naked" is not in the best place. So let's try another alternative: void foo() { naked asm { ... } } (To do that attributes have to be usable inside functions too). Bye, bearophile
Nov 27 2009
parent reply Don <nospam nospam.com> writes:
Denis Koroskin wrote:
 On Fri, 27 Nov 2009 12:50:19 +0300, bearophile 
 <bearophileHUGS lycos.com> wrote:
 
 Walter Bright:
 Naked is not an externally visible attribute of a function, signature or
   type, it only concerns the internals. Therefore, it shouldn't be an
 attribute.

On the other hand I agree with them that currently "naked" is not in the best place. So let's try another alternative: void foo() { naked asm { ... } }

No, it applies naked to an asm block, which is misleading: naked should be applied to the whole function body.

Yes, but if a function is naked, it should be illegal for it to contain any non-asm executable code. The compiler can't generate correct code when it's in a naked function. For all it knows, the function might even have swapped stack pointers! I believe D is quite correct in making 'naked' an asm instruction. Not all CPUs might support it. (It's only relevant for CPUs/compilers where a frame pointer is used).
 void foo()
  naked body
 {

LOL! Spam filters would love that!!
Nov 27 2009
parent Don <nospam nospam.com> writes:
Denis Koroskin wrote:
 On Fri, 27 Nov 2009 13:58:59 +0300, Don <nospam nospam.com> wrote:
 
 Denis Koroskin wrote:
 On Fri, 27 Nov 2009 12:50:19 +0300, bearophile 
 <bearophileHUGS lycos.com> wrote:

 Walter Bright:
 Naked is not an externally visible attribute of a function, 
 signature or
   type, it only concerns the internals. Therefore, it shouldn't be an
 attribute.

On the other hand I agree with them that currently "naked" is not in the best place. So let's try another alternative: void foo() { naked asm { ... } }

should be applied to the whole function body.

Yes, but if a function is naked, it should be illegal for it to contain any non-asm executable code. The compiler can't generate correct code when it's in a naked function. For all it knows, the function might even have swapped stack pointers!

I definitely saw code that uses D inside naked functions (and wrote such code myself). There is an example in src/druntime/src/compiler/dmd/rt/trace.d I agree it might not be portable, but so is any code written in asm.

Thanks, that one should be changed. It's just a call to a void function, and should be changed to a single call instruction. It wouldn't compile in LDC.
 In fact, I'm using naked to make code /more portable/ in my DynamicCall
 module:
 
 void push(T)(T arg)    // pass an argument to a function however compiler
                        // wants (e.g. pass argument in EAX, if it fits)
 {
       asm { naked; ret; }
 }
 
 void invokeFunction(void* funcptr, Arg arg)
 {
       switch (arg.type) {
           case ArgType.Float:
               // so that I don't care how exactly floating-point variables
               // are passed to function, let compiler do it for me
               push!(float)(*cast(float*)arg.ptr);
               break;
           ...
       }
 
       asm { call funcptr; }
 }
 
 (This is a simplified code for a single-argument function call)
 
 I'm not sure how correct it is, though (I asked for a comment but no one 
 answered).

That doesn't involve any mixing of naked and D in a single function. Of course, your 'push' function leaves the stack in a corrupt state. Definitely an unsafe function!
 I believe D is quite correct in making 'naked' an asm instruction. Not 
 all CPUs might support it. (It's only relevant for CPUs/compilers 
 where a frame pointer is used).

Sure, but it only makes naked a vendor-specific extension, it doesn't make it illegal to use. Since it's not a user-defined annotation those compilers that don't support would just issue a compile-time error (the same way they would do it for asm { naked; } so it's just a matter of syntax). I prefer it to be an annotation because it's not an asm instruction at all. It has a lot in common with extern (Foo), so I'd like for them share syntax, too ( extern(C) void* malloc(size_t size); ?)

It's absolutely none of the caller's business whether the function is naked. Naked has no consequences outside of the function body.
 void foo()
  naked body
 {

LOL! Spam filters would love that!!

Indeed!

Nov 27 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 27 Nov 2009 12:50:19 +0300, bearophile <bearophileHUGS lycos.com>  
wrote:

 Walter Bright:
 Naked is not an externally visible attribute of a function, signature or
   type, it only concerns the internals. Therefore, it shouldn't be an
 attribute.

On the other hand I agree with them that currently "naked" is not in the best place. So let's try another alternative: void foo() { naked asm { ... } }

No, it applies naked to an asm block, which is misleading: naked should be applied to the whole function body. More like void foo() naked body { // ... } But I still prefer naked void foo();, especially since there was a movement towards drop of body keyword (see My Body Is Ugly thread).
 (To do that attributes have to be usable inside functions too).

 Bye,
 bearophile

Nov 27 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 27 Nov 2009 13:58:59 +0300, Don <nospam nospam.com> wrote:

 Denis Koroskin wrote:
 On Fri, 27 Nov 2009 12:50:19 +0300, bearophile  
 <bearophileHUGS lycos.com> wrote:

 Walter Bright:
 Naked is not an externally visible attribute of a function, signature  
 or
   type, it only concerns the internals. Therefore, it shouldn't be an
 attribute.

On the other hand I agree with them that currently "naked" is not in the best place. So let's try another alternative: void foo() { naked asm { ... } }

should be applied to the whole function body.

Yes, but if a function is naked, it should be illegal for it to contain any non-asm executable code. The compiler can't generate correct code when it's in a naked function. For all it knows, the function might even have swapped stack pointers!

I definitely saw code that uses D inside naked functions (and wrote such code myself). There is an example in src/druntime/src/compiler/dmd/rt/trace.d I agree it might not be portable, but so is any code written in asm. In fact, I'm using naked to make code /more portable/ in my DynamicCall module: void push(T)(T arg) // pass an argument to a function however compiler // wants (e.g. pass argument in EAX, if it fits) { asm { naked; ret; } } void invokeFunction(void* funcptr, Arg arg) { switch (arg.type) { case ArgType.Float: // so that I don't care how exactly floating-point variables // are passed to function, let compiler do it for me push!(float)(*cast(float*)arg.ptr); break; ... } asm { call funcptr; } } (This is a simplified code for a single-argument function call) I'm not sure how correct it is, though (I asked for a comment but no one answered).
 I believe D is quite correct in making 'naked' an asm instruction. Not  
 all CPUs might support it. (It's only relevant for CPUs/compilers where  
 a frame pointer is used).

Sure, but it only makes naked a vendor-specific extension, it doesn't make it illegal to use. Since it's not a user-defined annotation those compilers that don't support would just issue a compile-time error (the same way they would do it for asm { naked; } so it's just a matter of syntax). I prefer it to be an annotation because it's not an asm instruction at all. It has a lot in common with extern (Foo), so I'd like for them share syntax, too ( extern(C) void* malloc(size_t size); ?)
 void foo()
  naked body
 {

LOL! Spam filters would love that!!

Indeed!
Nov 27 2009
prev sibling parent "Danny Wilson" <bluezenix gmail.com> writes:
Op Fri, 27 Nov 2009 11:58:59 +0100 schreef Don <nospam nospam.com>:

 void foo()
  naked body
 {

LOL! Spam filters would love that!!

I can already imagine the jokes spreading over the internets: safe public double penetration(of a) naked body { ... }
Nov 27 2009
prev sibling next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Don (nospam nospam.com)'s article
 It seems that pure and nothrow are attributes, just like  safe.
 (By contrast, you can overload functions based on const and immutable).
 Should the names be changed?

Vote++. Now that we have attributes, I think this is a no brainer from a consistency perspective.
Nov 26 2009
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Don wrote:
 It seems that pure and nothrow are attributes, just like  safe.
 (By contrast, you can overload functions based on const and immutable).
 Should the names be changed?

Definitely. And what about deprecated and override? -Lars
Nov 27 2009
prev sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Don wrote:
 It seems that pure and nothrow are attributes, just like  safe.
 (By contrast, you can overload functions based on const and immutable).
 Should the names be changed?

This runs into another issue I was thinking about. So I'm working on this property rewrite thing that does the following: foo.prop.func(); becomes auto t = foo.prop; t.func(); foo.prop = t.func(); This of course assumes that calling t.func() will mutate t. But, as I understand it, pure member functions can't mutate their aggregates. So if func() was pure, then foo.prop.func() shouldn't be rewritten, and the setter for prop should never be called. This would mean that pure would change the behavior of a program. Now, if attributes are not allowed to change the behavior of a program and property expressions are rewritten correctly, then pure would contradict itself. Note: This has less to do with pure itself, and more to do with the idea that pure functions only work with immutable data. The property rewriting couldn't care less whether or not the function is deterministic, but it does care about whether or not a function's arguments are lvalues (ex: ref parameters), including the hidden argument containing the aggregate in method calls. For a (slightly) more concrete example of why this matters: import std.stdio; struct IntProxy { int data; pure IntProxy opAdd(IntProxy other) { IntProxy ip; ip.data = data + other.data; return ip; } IntProxy opAddAssign(IntProxy other) { this.data++; return this; } } class Foo { IntProxy bar; IntProxy prop() { return bar; } } void main() { Foo foo = new Foo(); IntProxy ip; foo.bar.data = 2; ip.data = 2; IntProxy result = foo.prop + ip; assert(result.data == 4); writefln("%s",result.data); } I expect this program to compile, run, and print "4". If pure were an annotation AND annotations couldn't change program behavior AND property expression rewrite were in place, then this program would fail to compile because there is no corresponding setter function for foo.prop. Due to annotations being passive, this requires the compiler to ignore the pure status of IntProxy.opAdd and treat it like any other impure function for purposes of property rewriting. The setter would then be needed to receive the possibly mutated IntProxy returned by prop.opAdd(ip). - Chad
Nov 27 2009