"Error: `TypeInfo` cannot be used with -betterC" on a CTFE function
Steven Schveighoffer
schveiguy at gmail.com
Fri Apr 12 15:24:38 UTC 2024
On Friday, 12 April 2024 at 00:04:48 UTC, Liam McGillivray wrote:
> Here's what I wanted to do.
>
> In the library I'm working on, there are various declarations
> for functions defined in an external C library following the
> line `extern (C) @nogc nothrow:`. Here are some examples of
> such declarations which have a `const(char)*` parameter:
>
> ```d
> void InitWindow(int width, int height, const(char)* title);
> void SetWindowTitle(const(char)* title);
> Shader LoadShader(const(char)* vsFileName, const(char)*
> fsFileName);
> ```
>
> I wanted to generate definitions of overloads of these
> functions using strings as parameters instead of
> `const(char)*`. For the `InitWindow` function shown above, the
> overload should be defined like this:
>
> ```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.
> or alternatively, like the following:
> ```d
> void InitWindow(int width, int height, string title) {
> InitWindow(width, height, title.toStringz);
> }
> ```
This will allocate from the GC.
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.
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.
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.
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.
-Steve
More information about the Digitalmars-d-learn
mailing list