"Error: `TypeInfo` cannot be used with -betterC" on a CTFE function

Liam McGillivray yoshi.pit.link.mario at gmail.com
Sun Apr 14 22:36:18 UTC 2024


On Friday, 12 April 2024 at 15:24:38 UTC, Steven Schveighoffer 
wrote:
>> ```d
>> void InitWindow(int width, int height, ref string title) {
>>     InitWindow(width, height, cast(const(char)*)title);
>> }
>> ```
>
> This is invalid, a string may not be zero-terminated. You can't 
> just cast.

Well, it did work when I tried it (using a string variable, not a 
literal of course). It displayed as it is supposed to. But from 
the information I can find on the web it looks like strings are 
sometimes but not `always` zero-terminated. Not a great look for 
the language. Are there any rules to determine when it is and 
when it isn't (for string variables)?

> So there are a few things to consider:
>
> 1. Is the string *transiently used*. That is, does the function 
> just quickly use the string and never refers to it again? Given 
> that this is raylib, the source is pretty readable, so you 
> should be able to figure this out.

I suppose. But if it turns out that the string is used 
continuously (as I assume to be the case with `InitWindow` and 
`SetWindowTitle`) and it doesn't make a copy of it, I imagine it 
would be difficult to design the function overload, as it would 
need to store a copy of the string somewhere. In that case, the 
only clean solution would be to have a global array of strings to 
store everything that's been passed to such functions, but that 
doesn't feel like a very satisfying solution. I may take a look 
inside some Raylib functions if I get back to this task.

> 2. If 1 is false, will it be saved in memory that is scannable 
> by the GC? This is one of the most pernicious issues with using 
> C libraries from D. In this case, you will need to either 
> allocate the memory with C `malloc` or pin the GC memory.

You mean that the GC can destroy objects that still have 
references from the C code?

> For transiently used strings, I would point you at the function 
> [`tempCString`](https://github.com/dlang/phobos/blob/0663564600edb3cce6e0925599ebe8a6da8c20fd/std/internal/cstring.d#L77), which allocates a temporary C string using malloc or a stack buffer, and then frees it when done with it.

Thank you. In a previous thread, someone told me that having to 
do many deallocations slows down the program, and the GC is more 
efficient because it deallocates many objects simultaneously. Is 
this something worth considering here, or is the overhead going 
to be tiny even when it's called a few times per frame?

> The obvious problem in all this is to avoid accepting string 
> literals (which are magic and automatically convert to const 
> char *). This is currently impossible with function 
> overloading, and so you need a separate function name, or put 
> them in a different module.

Aren't there any compile-time conditions for this?


More information about the Digitalmars-d-learn mailing list