Thread overview
assert(__ctfe) and betterC
Jan 27, 2021
Tim
Jan 27, 2021
Tim
Jan 28, 2021
Walter Bright
January 27, 2021
CTFE is the primary vehicle used to generate dynamic mixin code based on template and regular parameters. Doing it with templates *only* is possible, but so so painful.

But, the general mechanisms used in CTFE to generate string data (i.e. string concatenation) are not available for betterC runtime code. And CTFE must be compiled to as runtime code before it is interpreted.

I remember something about assert(__ctfe) in your function telling the compiler to not emit the code to the object file. Did that get in? Is there a way we can use that to turn off betterC too?

Otherwise, you get errors when building your CTFE function because "TypeInfo cannot be used with -betterC"

Is there another way I can do this?

-Steve
January 27, 2021
On Wednesday, 27 January 2021 at 20:59:24 UTC, Steven Schveighoffer wrote:
> CTFE is the primary vehicle used to generate dynamic mixin code based on template and regular parameters. Doing it with templates *only* is possible, but so so painful.
>
> But, the general mechanisms used in CTFE to generate string data (i.e. string concatenation) are not available for betterC runtime code. And CTFE must be compiled to as runtime code before it is interpreted.
>
> I remember something about assert(__ctfe) in your function telling the compiler to not emit the code to the object file. Did that get in? Is there a way we can use that to turn off betterC too?
>
> Otherwise, you get errors when building your CTFE function because "TypeInfo cannot be used with -betterC"
>
> Is there another way I can do this?
>
> -Steve

One way I have sometimes used is an alias to a function literal:

alias generateVar = function(string name) {
    return "int " ~ name ~ ";";
};

mixin(generateVar("i"));

extern(C) int main()
{
    i = 0;
    return i;
}

This works with betterC.
January 27, 2021
On 1/27/21 4:05 PM, Tim wrote:
> On Wednesday, 27 January 2021 at 20:59:24 UTC, Steven Schveighoffer wrote:
>> Is there another way I can do this?
>>
> 
> One way I have sometimes used is an alias to a function literal:
> 
> alias generateVar = function(string name) {
>      return "int " ~ name ~ ";";
> };
> 
> mixin(generateVar("i"));
> 
> extern(C) int main()
> {
>      i = 0;
>      return i;
> }
> 
> This works with betterC.

Well, that works great! What a nice... well, I have no idea why this works. But thank you!

-Steve
January 27, 2021
On Wednesday, 27 January 2021 at 21:27:45 UTC, Steven Schveighoffer wrote:
> Well, that works great! What a nice... well, I have no idea why this works. But thank you!
>
> -Steve

As far as I understand, the function literal can't be compiled at the definition, because attributes and parameter types may need to be inferred at the call site. Since the only call site is inside a mixin, it is never compiled for runtime and no checks for betterC need to be performed.
January 27, 2021
On Wednesday, 27 January 2021 at 21:27:45 UTC, Steven Schveighoffer wrote:
> On 1/27/21 4:05 PM, Tim wrote:
>> On Wednesday, 27 January 2021 at 20:59:24 UTC, Steven Schveighoffer wrote:
>>> Is there another way I can do this?
>>>
>> 
>> One way I have sometimes used is an alias to a function literal:
>> 
>> alias generateVar = function(string name) {
>>      return "int " ~ name ~ ";";
>> };
>> 
>> mixin(generateVar("i"));
>> 
>> extern(C) int main()
>> {
>>      i = 0;
>>      return i;
>> }
>> 
>> This works with betterC.
>
> Well, that works great! What a nice... well, I have no idea why this works. But thank you!
>
> -Steve

`enum` also works:

enum generateVar = (string name) => "int " ~ name ~ ";";

The key difference between these ways of defining a function and the regular way, is that with them it's guaranteed that the compiler won't codegen them since simply  it only does this for regular functions.

assert(__ctfe) could be made to work, but it's wrong way to go about things. Instead the compiler should only code-gen what is actually necessary.

In the posts below I have sketched out how a scheme for fully on-demand codegen might look like, based on `export` inference:

https://forum.dlang.org/post/xbllqrpvflazfpowizwj@forum.dlang.org
https://forum.dlang.org/post/nvvgrdlucajshjngdjlj@forum.dlang.org

January 27, 2021
On 1/27/2021 12:59 PM, Steven Schveighoffer wrote:
> I remember something about assert(__ctfe) in your function telling the compiler to not emit the code to the object file. Did that get in? Is there a way we can use that to turn off betterC too?

In oper.d there are some lambdas which generate static information, and the lambdas are not emitted to the object file.

https://github.com/dlang/dmd/blob/master/src/dmd/backend/oper.d#L387

This capability is what eliminated the need for the optabgen.d file.