www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - CTFE attribute

reply Manu <turkeyman gmail.com> writes:
This has come up lots of times before.. I just wanted to effectively +1
this request.

I have some templates, and some reasonably complex functions I use strictly
via CTFE to produce enums and evaluate conditions within the templates.
When I build my code, I notice that the CTFE functions, which are never
referenced in any runtime code, are still present in the object file.
Additionally, one of these functions requires I import std.string, which is
only used in CTFE code, and is otherwise a pointless import.

I'd certainly like to be able to mark these functions CTFE to be sure no
runtime code will ever be generated for them, and also, what can I do about
CTFE imports? I don't want that import in my binary...
Jan 28 2012
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 28/01/2012 14:50, Manu wrote:
 This has come up lots of times before.. I just wanted to effectively +1
 this request.

 I have some templates, and some reasonably complex functions I use
 strictly via CTFE to produce enums and evaluate conditions within the
 templates.
 When I build my code, I notice that the CTFE functions, which are never
 referenced in any runtime code, are still present in the object file.
 Additionally, one of these functions requires I import std.string, which
 is only used in CTFE code, and is otherwise a pointless import.

 I'd certainly like to be able to mark these functions CTFE to be sure no
 runtime code will ever be generated for them, and also, what can I do
 about CTFE imports? I don't want that import in my binary...
There are a couple of things you can do. The first is to make the imports function local, the second is: http://www.digitalmars.com/d/archives/digitalmars/D/Incremental_compilation_with_DMD_96138.html#N96337 You'll notice that thread mentions a pragma(ctfe) patch for DMD, that's another option, though would require a patched compiler. I can't seem to find a link to that patch, a bit of googling should help though. Another idea I've just had: T myComplexFuntion() { if (__ctfe) { // Implement here } else { assert(0); } } This should allow the function to be inlined to assert(0); if it's called at runtime, so while it will still exist in the binary, it won't introduce lots of additional bloat. -- Robert http://octarineparrot.com/
Jan 28 2012
parent reply Manu <turkeyman gmail.com> writes:
On 28 January 2012 17:03, Robert Clipsham <robert octarineparrot.com> wrote:

 On 28/01/2012 14:50, Manu wrote:

 This has come up lots of times before.. I just wanted to effectively +1
 this request.

 I have some templates, and some reasonably complex functions I use
 strictly via CTFE to produce enums and evaluate conditions within the
 templates.
 When I build my code, I notice that the CTFE functions, which are never
 referenced in any runtime code, are still present in the object file.
 Additionally, one of these functions requires I import std.string, which
 is only used in CTFE code, and is otherwise a pointless import.

 I'd certainly like to be able to mark these functions CTFE to be sure no
 runtime code will ever be generated for them, and also, what can I do
 about CTFE imports? I don't want that import in my binary...
There are a couple of things you can do. The first is to make the imports function local, the second is: http://www.digitalmars.com/d/**archives/digitalmars/D/** Incremental_compilation_with_**DMD_96138.html#N96337<http://www.digitalmars.com/d/archives/digitalmars/D/Incremental_compilation_with_DMD_96138.html#N96337> You'll notice that thread mentions a pragma(ctfe) patch for DMD, that's another option, though would require a patched compiler. I can't seem to find a link to that patch, a bit of googling should help though. Another idea I've just had: T myComplexFuntion() { if (__ctfe) { // Implement here } else { assert(0); } } This should allow the function to be inlined to assert(0); if it's called at runtime, so while it will still exist in the binary, it won't introduce lots of additional bloat.
Sweet, I'll do that for now. You mean static if() right?
Jan 28 2012
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 28/01/2012 15:13, Manu wrote:
 Sweet, I'll do that for now.
 You mean static if() right?
No, I mean if(). __ctfe is a magic variable, and during CTFE it is true, at run time it is false. As it is a variable and not a constant, it cannot be read at compile time, so static if() won't work. See also: http://dlang.org/function ctrl+f for __ctfe -- Robert http://octarineparrot.com/
Jan 28 2012
parent reply Mehrdad <wfunction hotmail.com> writes:
On 1/28/2012 7:24 AM, Robert Clipsham wrote:
 On 28/01/2012 15:13, Manu wrote:
 Sweet, I'll do that for now.
 You mean static if() right?
No, I mean if(). __ctfe is a magic variable, and during CTFE it is true, at run time it is false. As it is a variable and not a constant, it cannot be read at compile time, so static if() won't work. See also: http://dlang.org/function ctrl+f for __ctfe
Why isn't it a constant? o.O
Jan 28 2012
next sibling parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Mehrdad" <wfunction hotmail.com> wrote in message 
news:jg1469$4a6$1 digitalmars.com...

 Why isn't it a constant? o.O
It isn't a compile-time constant, it is constant. You need to use if, not static if, because code versioned out with static if does not get processed in the compiler beyond parsing. It needs to be done with a normal code branch that is always taken when in the interpreter but never taken at runtime.
Jan 28 2012
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Mehrdad:

 Why isn't it a constant? o.O
Unspecified implementation difficulties. Bye, bearophile
Jan 28 2012
prev sibling next sibling parent reply Trass3r <un known.com> writes:
 When I build my code, I notice that the CTFE functions, which are never
 referenced in any runtime code, are still present in the object file.
For now you can get rid of it with -L--gc-sections (or LTO). gdc also needs -ffunction-sections -fdata-sections.
Jan 28 2012
parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 28.01.2012, 16:42 Uhr, schrieb Trass3r <un known.com>:

 When I build my code, I notice that the CTFE functions, which are never
 referenced in any runtime code, are still present in the object file.
For now you can get rid of it with -L--gc-sections (or LTO). gdc also needs -ffunction-sections -fdata-sections.
I've recently fucked up my first executable with that. -L--gc-sections had the effect as if 'throw' was a no-op. In other words runtime exceptions are silently ignored. If you use it double-check that exceptions are still thrown!
Jan 29 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/28/2012 6:50 AM, Manu wrote:
 I'd certainly like to be able to mark these functions CTFE to be sure no
runtime
 code will ever be generated for them, and also, what can I do about CTFE
 imports? I don't want that import in my binary...
Being in your object file doesn't mean they make it into the binary. Optlink, for example, will remove unreferenced COMDATs.
Jan 28 2012
next sibling parent reply Manu <turkeyman gmail.com> writes:
On 28 January 2012 20:39, Walter Bright <newshound2 digitalmars.com> wrote:

 On 1/28/2012 6:50 AM, Manu wrote:

 I'd certainly like to be able to mark these functions CTFE to be sure no
 runtime
 code will ever be generated for them, and also, what can I do about CTFE
 imports? I don't want that import in my binary...
Being in your object file doesn't mean they make it into the binary. Optlink, for example, will remove unreferenced COMDATs.
I still don't want it polluting my lib, and I also don't want the possibility that someone COULD link to it. It's simply not runtime code. Additionally, while the code is still present in my lib, so must be the import that it makes use of... I'd also like an error if the function were called outside of CTFE... so the CTFE attribute others have discussed seems like a good idea to me.
Jan 28 2012
next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Saturday, 28 January 2012 at 19:02:56 UTC, Manu wrote:
 I still don't want it polluting my lib, and I also don't want 
 the possibility that someone COULD link to it. It's simply not 
 runtime code. Additionally, while the code is still present in 
 my lib, so must be the import that it makes use of...

 I'd also like an error if the function were called outside of 
 CTFE... so the CTFE attribute others have discussed seems like 
 a good idea to me.
You could make it private, and expose it via a template. template foo(ARGS...) { enum foo = fooImpl!(ARGS)(); } private auto fooImpl(ARGS...)() { // ... } Phobos uses this idiom often, but mainly because CTFE is more flexible that template metaprogramming. Additionally, simply making the function templated would prevent it from ending up in your library's object file. You can make any regular function templated with an empty template parameter list: void foo()(...) { ... }
Jan 28 2012
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/28/2012 11:02 AM, Manu wrote:
 I'd also like an error if the function were called outside of CTFE...
if (!ctfe) assert(0);
Jan 28 2012
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/28/2012 12:38 PM, Walter Bright wrote:
 On 1/28/2012 11:02 AM, Manu wrote:
 I'd also like an error if the function were called outside of CTFE...
if (!ctfe) assert(0);
Oops, if (!__ctfe) assert(0);
Jan 28 2012
prev sibling parent Don Clugston <dac nospam.com> writes:
On 28/01/12 19:39, Walter Bright wrote:
 On 1/28/2012 6:50 AM, Manu wrote:
 I'd certainly like to be able to mark these functions CTFE to be sure
 no runtime
 code will ever be generated for them, and also, what can I do about CTFE
 imports? I don't want that import in my binary...
Being in your object file doesn't mean they make it into the binary. Optlink, for example, will remove unreferenced COMDATs.
The problem is how to prevent the moduleinfo from getting linked in. Though this is a general problem, not specific to CTFE. One thing I have been considering is, if a template is only ever instantiated in CTFE (eg in a static if, or while defining an enum value), should it still get written into the obj file? I don't think it is ever necessary, and discarding it would save a lot of space and time.
Jan 30 2012