digitalmars.D - pure and custom new / delete
- Benjamin Thaut (10/10) Jun 26 2012 As delete and new / delete overloading is deprecated and it was
- Timon Gehr (3/13) Jun 26 2012 You can cast function pointers to pure, or mark extern(C) memory
- Benjamin Thaut (7/22) Jun 26 2012 extern(c) is not an options as there is a structure of various different...
- Timon Gehr (4/27) Jun 26 2012 You can examine the assembly code. DMD is perhaps not smart enough (it
- Benjamin Thaut (6/37) Jun 26 2012 The more I get into this, the more I get the feeling that all this "D
- David Nadlinger (7/22) Jun 26 2012 This has nothing to do with the GC, just with the compiler
- Benjamin Thaut (4/23) Jun 26 2012 I'm not talking about the optimization here. I'm talking about not
- Steven Schveighoffer (37/42) Jun 26 2012 extern(C) does not mean implemented in C, it just means C linkage. You ...
- Benjamin Thaut (5/49) Jun 26 2012 Thanks this works, but it seems to be a very ugly hack just to work
- Jonathan M Davis (10/14) Jun 26 2012 Note that since telling the compiler something is pure when it doesn't t...
- David Nadlinger (23/30) Jun 26 2012 I created it specifically for a related use case, but on its own,
- Steven Schveighoffer (13/17) Jun 26 2012 Um... yeah :) If you are working around the type system, it *should* be...
- David Nadlinger (6/8) Jun 26 2012 I can only second that – especially because depending on what
As delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so. But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this? Kind Regards Benjamin Thaut
Jun 26 2012
On 06/26/2012 05:59 PM, Benjamin Thaut wrote:As delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so. But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this? Kind Regards Benjamin ThautYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.
Jun 26 2012
Am 26.06.2012 18:02, schrieb Timon Gehr:On 06/26/2012 05:59 PM, Benjamin Thaut wrote:extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D. Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it? Kind Regards Benjamin ThautAs delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so. But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this? Kind Regards Benjamin ThautYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.
Jun 26 2012
On 06/26/2012 06:05 PM, Benjamin Thaut wrote:Am 26.06.2012 18:02, schrieb Timon Gehr:You can examine the assembly code. DMD is perhaps not smart enough (it is unable to inline directly called function literals, so I am not optimistic.) LDC and GDC should certainly optimize it out.On 06/26/2012 05:59 PM, Benjamin Thaut wrote:extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D. Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it? Kind Regards Benjamin ThautAs delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so. But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this? Kind Regards Benjamin ThautYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.
Jun 26 2012
Am 26.06.2012 18:44, schrieb Timon Gehr:On 06/26/2012 06:05 PM, Benjamin Thaut wrote:The more I get into this, the more I get the feeling that all this "D can be used without a GC" is just a marketing trick to get C++ guys to use D. I really like D because of a lot of nice features it has, but at the current rate I fear that the day I go back to c++ will come.Am 26.06.2012 18:02, schrieb Timon Gehr:You can examine the assembly code. DMD is perhaps not smart enough (it is unable to inline directly called function literals, so I am not optimistic.) LDC and GDC should certainly optimize it out.On 06/26/2012 05:59 PM, Benjamin Thaut wrote:extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D. Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it? Kind Regards Benjamin ThautAs delete and new / delete overloading is deprecated and it was recommeneded to write tempaltes to repalce these expressions I did so. But now as everything starts to work out pretty nice I've walked into the 'purity' issue. Pure functions are only allowed to call other pure functions and as far as I know there is no way to make functions "trusted pure". But I would need to make certain functions "trused pure", espeically my new and delete replacements. Any suggestions how to do this? Kind Regards Benjamin ThautYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.
Jun 26 2012
On Tuesday, 26 June 2012 at 16:52:48 UTC, Benjamin Thaut wrote:Am 26.06.2012 18:44, schrieb Timon Gehr:This has nothing to do with the GC, just with the compiler turning an indirect jump to a statically known address into a direct one. Every decent compiler should optimize it away, and even if it doesn't, it still won't kill you in 99.9% of the use cases. DavidOn 06/26/2012 06:05 PM, Benjamin Thaut wrote:The more I get into this, the more I get the feeling that all this "D can be used without a GC" is just a marketing trick to get C++ guys to use D.Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it? […]You can examine the assembly code. DMD is perhaps not smart enough (it is unable to inline directly called function literals, so I am not optimistic.) LDC and GDC should certainly optimize it out.
Jun 26 2012
Am 26.06.2012 19:23, schrieb David Nadlinger:On Tuesday, 26 June 2012 at 16:52:48 UTC, Benjamin Thaut wrote:I'm not talking about the optimization here. I'm talking about not beeing able to do a propper replacement for new / delete with the features the language currently has.Am 26.06.2012 18:44, schrieb Timon Gehr:This has nothing to do with the GC, just with the compiler turning an indirect jump to a statically known address into a direct one. Every decent compiler should optimize it away, and even if it doesn't, it still won't kill you in 99.9% of the use cases. DavidOn 06/26/2012 06:05 PM, Benjamin Thaut wrote:The more I get into this, the more I get the feeling that all this "D can be used without a GC" is just a marketing trick to get C++ guys to use D.Is the compiler smart enough to optimize away a function pointer I created localy just so I can cast it? […]You can examine the assembly code. DMD is perhaps not smart enough (it is unable to inline directly called function literals, so I am not optimistic.) LDC and GDC should certainly optimize it out.
Jun 26 2012
On Tue, 26 Jun 2012 12:05:55 -0400, Benjamin Thaut <code benjamin-thaut.de> wrote:Am 26.06.2012 18:02, schrieb Timon Gehr:extern(C) does not mean implemented in C, it just means C linkage. You can use arrays, classes, etc. in extern(C) functions. UFCS makes this really easy too: myalloc.d: interface Allocator { void * _alloc(size_t size); } extern(C) void *alloc(Allocator a, size_t size) pure; allocimpl.d: import myalloc; extern(C) void *alloc(Allocator a) // pure { return a._alloc(size) } mallocer.d: public import myalloc; import std.c.stdlib; // sample allocator class Mallocer : Allocator { void *_alloc(size_t size) { return malloc(size);} } main.d: import mallocer; void foo(Allocator a) pure { a.alloc(200); //a._alloc(200); // fails as expected } void main() { foo(new Mallocer); } -SteveYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D.
Jun 26 2012
Am 26.06.2012 19:19, schrieb Steven Schveighoffer:On Tue, 26 Jun 2012 12:05:55 -0400, Benjamin Thaut <code benjamin-thaut.de> wrote:Thanks this works, but it seems to be a very ugly hack just to work around the type system. Also I have templated allocator functions I can not use this trick on. This is going to be a lot of work to get done properly, so I just ignore pure for now I think.Am 26.06.2012 18:02, schrieb Timon Gehr:extern(C) does not mean implemented in C, it just means C linkage. You can use arrays, classes, etc. in extern(C) functions. UFCS makes this really easy too: myalloc.d: interface Allocator { void * _alloc(size_t size); } extern(C) void *alloc(Allocator a, size_t size) pure; allocimpl.d: import myalloc; extern(C) void *alloc(Allocator a) // pure { return a._alloc(size) } mallocer.d: public import myalloc; import std.c.stdlib; // sample allocator class Mallocer : Allocator { void *_alloc(size_t size) { return malloc(size);} } main.d: import mallocer; void foo(Allocator a) pure { a.alloc(200); //a._alloc(200); // fails as expected } void main() { foo(new Mallocer); } -SteveYou can cast function pointers to pure, or mark extern(C) memory allocation functions as pure.extern(c) is not an options as there is a structure of various different allocators that implement a common interface which all is written in D.
Jun 26 2012
On Tuesday, June 26, 2012 20:08:14 Benjamin Thaut wrote:Thanks this works, but it seems to be a very ugly hack just to work around the type system. Also I have templated allocator functions I can not use this trick on. This is going to be a lot of work to get done properly, so I just ignore pure for now I think.Note that since telling the compiler something is pure when it doesn't think so _is_ forcing the type system, it's not entirely unreasonable that it not be super-easy to do. However, it would definitely be nice if it were a lot easier than it is. You could try std.traits.SetFunctionAttributes (it was recently added and is not in 2.59 IIRC). David Nadlinger created it specifically for being able to create easily add function attributes such as pure to a function. I haven't messed around with it yet, but it looks very easy to use. - Jonathan M Davis
Jun 26 2012
On Tuesday, 26 June 2012 at 18:35:31 UTC, Jonathan M Davis wrote:You could try std.traits.SetFunctionAttributes (it was recently added and is not in 2.59 IIRC). David Nadlinger created it specifically for being able to create easily add function attributes such as pure to a function. I haven't messed around with it yet, but it looks very easy to use.I created it specifically for a related use case, but on its own, SetFunctionAttributes is strictly for manipulating function/delegate _types_ in terms of linkage. This is helpful because the D grammar for function types is quite clumsy. For example, the following is not valid D code, and can't trivially be corrected (in the first case, creating a separate alias for the function type would work, but that's clumsy especially in generic and/or generated code): --- void foo(extern(C) void function() nothrow cb); auto assumePure(T)(T t) { return cast(pure T)(t); } --- As mentioned in https://github.com/D-Programming-Language/phobos/pull/555, it would be easy to add »high-level primitives« on top of SetFunctionAttributes; assumePure and ExternC templates are included as examples its the documentation. Specifically for declaring »trusted pure« functions, making »alias assumePure!funcImpl func;« work would not be hard either. I just was not sure which of those tools are needed frequently enough to warrant inclusion in Phobos, if any. David
Jun 26 2012
On Tue, 26 Jun 2012 14:08:14 -0400, Benjamin Thaut <code benjamin-thaut.de> wrote:Thanks this works, but it seems to be a very ugly hack just to work around the type system. Also I have templated allocator functions I can not use this trick on. This is going to be a lot of work to get done properly, so I just ignore pure for now I think.Um... yeah :) If you are working around the type system, it *should* be ugly! Note that you should be *extremely* careful of saying something is pure when it is not typechecked by the compiler. If I were designing such an allocator system, I'd separate out pure and impure allocators into two separate hierarchies, and let the person implementing the actual underlying allocator jump the fence between pure and impure. For example, in the code I gave, really only C malloc should be forced-pure, everything else should be typechecked as pure by the compiler. But you were asking for a specific solution. -Steve
Jun 26 2012
On Tuesday, 26 June 2012 at 19:48:26 UTC, Steven Schveighoffer wrote:Note that you should be *extremely* careful of saying something is pure when it is not typechecked by the compiler.I can only second that – especially because depending on what the signature of the function is, the compiler might optimize out calls to them. David
Jun 26 2012