Thread overview
How to use @safe when a C library integration needed
Jan 23, 2023
Leonardo
Jan 23, 2023
Dom DiSc
Apr 14, 2023
Leonardo
Apr 14, 2023
Paul Backus
Apr 15, 2023
Leonardo
January 23, 2023

Hello. How to use @safe when a C library integration needed?

Everything need a system function...

January 23, 2023

On Monday, 23 January 2023 at 16:36:21 UTC, Leonardo wrote:

>

Hello. How to use @safe when a C library integration needed?

Everything need a system function...

@safe fn()
{
   // lot of safe stuff

   () @trusted {
       // in this block[*] @system function like extern C can be called.
       // you need to make sure the API is used correct
       @assert(/*C_Fun is safe to be used with param1*/);
       @assert(/*C_Fun is safe to be used with param2*/);
       C_Fun(param1, param2);
   }();

   // more safe stuff

}

[*] in fact, this is a lambda function that is directly called, because real trusted blocks are not allowed (yet).

April 14, 2023

On Monday, 23 January 2023 at 16:46:48 UTC, Dom DiSc wrote:

>

On Monday, 23 January 2023 at 16:36:21 UTC, Leonardo wrote:

>

Hello. How to use @safe when a C library integration needed?

Everything need a system function...

@safe fn()
{
   // lot of safe stuff

   () @trusted {
       // in this block[*] @system function like extern C can be called.
       // you need to make sure the API is used correct
       @assert(/*C_Fun is safe to be used with param1*/);
       @assert(/*C_Fun is safe to be used with param2*/);
       C_Fun(param1, param2);
   }();

   // more safe stuff

}

[*] in fact, this is a lambda function that is directly called, because real trusted blocks are not allowed (yet).

Thanks. But this works only to one function per time. Is there any way to do this to an imported library at all? something like @trusted import library

April 14, 2023

On Friday, 14 April 2023 at 14:10:41 UTC, Leonardo wrote:

>

Thanks. But this works only to one function per time. Is there any way to do this to an imported library at all? something like @trusted import library

No, there isn't. C is an unsafe language, so if you want to call C from @safe code, you have to do the work to make sure that each individual call is @safe.

If you are calling the same C function many times from @safe code, you can write a @trusted D wrapper function to avoid repeating the safety checks at every call site. For example, here's a @trusted wrapper for the standard C library function puts:

import core.stdc.stdio: puts;
import std.exception: enforce;

@trusted
void safePuts(const(char)[] s)
{
    // To safely call puts, we must pass it a valid C string
    // To be a valid C string, s must be non-empty and NUL-terminated
    enforce(s.length > 0, "An empty string is not a C string");
    enforce(s[$-1] == '\0', "A C string must be NUL-terminated");

    // If the checks above have passed, this call is safe
    puts(&s[0]);
}
April 15, 2023

On Friday, 14 April 2023 at 16:19:22 UTC, Paul Backus wrote:

>

On Friday, 14 April 2023 at 14:10:41 UTC, Leonardo wrote:

>

[...]

No, there isn't. C is an unsafe language, so if you want to call C from @safe code, you have to do the work to make sure that each individual call is @safe.

[...]

Thanks for your response.