Repository: JuliaLang/julia
File: base/c.jl (Julia)

Code before:

This calls the C standard library function:

    size_t strlen(char *)

with a Julia variable named `s`. See also `ccall`.

Varargs are supported with the following convention:

    @ccall printf("%s = %d"::Cstring ; "foo"::Cstring, foo::Cint)::Cint

The semicolon is used to separate required arguments (of which there
must be at least one) from variadic arguments.

Example using an external library:

    # C signature of g_uri_escape_string:
    # char *g_uri_escape_string(const char *unescaped, const char *reserved_chars_allowed, gboolean allow_utf8);

    const glib = "libglib-2.0"
    @ccall glib.g_uri_escape_string(my_uri::Cstring, ":/"::Cstring, true::Cint)::Cstring

The string literal could also be used directly before the function
name, if desired `"libglib-2.0".g_uri_escape_string(...`

It's possible to declare the ccall as `gc_safe` by using the `gc_safe = true` option:
    @ccall gc_safe=true strlen(s::Cstring)::Csize_t
This allows the garbage collector to run concurrently with the ccall, which can be useful whenever
the `ccall` may block outside of julia.
WARNING: This option should be used with caution, as it can lead to undefined behavior if the ccall
calls back into the julia runtime. (`@cfunction`/`@ccallables` are safe however)
"""
macro ccall(exprs...)
    return ccall_macro_lower((:ccall), ccall_macro_parse(exprs)...)
end

macro ccall_effects(effects::UInt16, expr)
    return ccall_macro_lower((:ccall, effects), ccall_macro_parse(expr)...)
end


Review comment (suggestion):
🚲 If `gc_safe=false` is the default, perhaps marking a `ccall` as `gc_safe` could just be spelled like:
```julia
@ccall :gc_safe strlen(s::Cstring)::Csize_t
```
(similar to how the `@atomic` and `@spawn` and `@assume_effects` macros take Symbols to control behaviour) 

Code after:
This calls the C standard library function:

    size_t strlen(char *)

with a Julia variable named `s`. See also `ccall`.

Varargs are supported with the following convention:

    @ccall printf("%s = %d"::Cstring ; "foo"::Cstring, foo::Cint)::Cint

The semicolon is used to separate required arguments (of which there
must be at least one) from variadic arguments.

Example using an external library:

    # C signature of g_uri_escape_string:
    # char *g_uri_escape_string(const char *unescaped, const char *reserved_chars_allowed, gboolean allow_utf8);

    const glib = "libglib-2.0"
    @ccall glib.g_uri_escape_string(my_uri::Cstring, ":/"::Cstring, true::Cint)::Cstring

The string literal could also be used directly before the function
name, if desired `"libglib-2.0".g_uri_escape_string(...`

It's possible to declare the ccall as `gc_safe` by using the `gc_safe = true` option:
    @ccall gc_safe=true strlen(s::Cstring)::Csize_t
This allows the garbage collector to run concurrently with the ccall, which can be useful whenever
the `ccall` may block outside of julia.
WARNING: This option should be used with caution, as it can lead to undefined behavior if the ccall
calls back into the julia runtime. (`@cfunction`/`@ccallables` are safe however)
"""
macro ccall(exprs...)
    return ccall_macro_lower((:ccall), ccall_macro_parse(exprs)...)
end

macro ccall_effects(effects::UInt16, expr)
    return ccall_macro_lower((:ccall, effects), ccall_macro_parse(expr)...)
end