add c-variadic function definitions#2177
add c-variadic function definitions#2177folkertdev wants to merge 2 commits intorust-lang:masterfrom
Conversation
| ## C-variadic functions | ||
|
|
||
| r[items.fn.c-variadic.intro] | ||
| A *c-variadic* function accepts a variable argument list `pat: ...` as its final parameter. |
There was a problem hiding this comment.
for c-variadic definitions only pat: ... is accepted semantically.
plain ... is currently parsed, the varargs_without_pattern lint is meant to eventually disallow it. This syntax can only be used as an input to macros, when a bare ... makes it past macro expansion, that will emit an error.
I didn't mention this here, but maybe we should: we follow C23 in that pat: ... may be the only argument. Earlier versions of C required at least one standard argument before the ....
| > [!WARNING] | ||
| > Passing an unexpected number of arguments or arguments of unexpected type to a variadic function may lead to [undefined behavior][undefined]. |
There was a problem hiding this comment.
copied from
basically, the responsibility for passing valid arguments is on the caller.
| unsafe extern "C" fn example() -> i32 { | ||
| let mut storage = MaybeUninit::<VaList<'_>>::uninit(); | ||
| va_start(storage.as_mut_ptr()); // Initializes the VaList. | ||
| let mut ap: &mut VaList<'_> = ap.assume_init_mut(); | ||
|
|
||
| unsafe { ap.arg::<i32>() } | ||
|
|
||
| va_end(ap) | ||
| } |
There was a problem hiding this comment.
va_start and va_end are C functions/concepts. We could instead handwave and say
let mut ap: VaList<'_> = /* ... */; // Initializes the VaList.the va_end is called by the VaList Drop implementation.
I think this has all of the raw material, but needs polishing.
Here is a draft of the stabilization report, for additional context: https://hackmd.io/@Q66MPiW4T7yNTKOCaEb-Lw/S1iI3WIwZg