-
Notifications
You must be signed in to change notification settings - Fork 583
add c-variadic function definitions #2177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,7 +83,7 @@ r[items.fn.params.self-restriction] | |
| Functions with a self parameter may only appear as an [associated function] in a [trait] or [implementation]. | ||
|
|
||
| r[items.fn.params.varargs] | ||
| A parameter with the `...` token indicates a [variadic function], and may only be used as the last parameter of an [external block] function. The variadic parameter may have an optional identifier, such as `args: ...`. | ||
| A parameter with the `...` token indicates a [c-variadic function], and may only be used as the last parameter. In an [`extern` block] the c-variadic parameter may have an optional identifier, such as `args: ...`, in a [c-variadic function definition] the identifier is mandatory. | ||
|
|
||
| r[items.fn.body] | ||
| ## Function body | ||
|
|
@@ -332,6 +332,82 @@ Note that this behavior is a consequence of the desugaring to a function that re | |
|
|
||
| Unsafe is used on an async function in precisely the same way that it is used on other functions: it indicates that the function imposes some additional obligations on its caller to ensure soundness. As in any other unsafe function, these conditions may extend beyond the initial call itself -- in the snippet above, for example, the `unsafe_example` function took a pointer `x` as argument, and then (when awaited) dereferenced that pointer. This implies that `x` would have to be valid until the future is finished executing, and it is the caller's responsibility to ensure that. | ||
|
|
||
| r[items.fn.c-variadic] | ||
| ## C-variadic functions | ||
|
|
||
| r[items.fn.c-variadic.intro] | ||
| A *c-variadic* function accepts a variable argument list `pat: ...` as its final parameter. | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for c-variadic definitions only plain I didn't mention this here, but maybe we should: we follow C23 in that
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is anything holding back changing
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not as far as I know. I can make that change an nominate for T-lang.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on rust-lang/rust#143619 (comment) there was only one actual impacted crate https://crates.io/crates/binrw. The issue was fixed in jam1garner/binrw#342, however there has not been a release since. So, if we made this warn in dependencies there would be nothing that users of that crate could do. I'll ping for a release with the fix.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like the releases happened: jam1garner/binrw#342 (comment)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, PR is up at rust-lang/rust#154599 |
||
|
|
||
| ```rust | ||
| unsafe extern "C" fn example(ap: ...) -> f64 { | ||
| unsafe { ap.next_arg::<f64>() } | ||
| } | ||
| ``` | ||
|
|
||
| This parameter stands in for an arbitrary number of arguments that may be passed by the caller. | ||
|
|
||
| > [!WARNING] | ||
| > Passing an unexpected number of arguments or arguments of unexpected type to a c-variadic function may lead to [undefined behavior][undefined]. | ||
|
|
||
| r[items.fn.c-variadic.c-variadic-parameter-type] | ||
| The type of `pat` in the function body is [`VaList`]. | ||
|
|
||
| r[items.fn.c-variadic.desugar-brief] | ||
| A c-variadic function definition is roughly equivalent to a function operating on a [`VaList`]. | ||
|
|
||
| ```rust | ||
| // Source | ||
| unsafe extern "C" fn example(mut ap: ...) -> i32 { | ||
| unsafe { ap.next_arg::<i32>() } | ||
| } | ||
| ``` | ||
|
|
||
| is roughly equivalent to: | ||
|
|
||
| ```rust | ||
| # use std::ffi::VaList; | ||
| // Desugared | ||
| unsafe extern "C" fn example() -> i32 { | ||
| let mut ap: VaList<'_> = /* compiler initializes the VaList */; | ||
|
|
||
| unsafe { ap.next_arg::<i32>() } | ||
|
|
||
| va_end(ap) | ||
| } | ||
|
Comment on lines
+370
to
+376
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
let mut ap: VaList<'_> = /* ... */; // Initializes the VaList.the |
||
| ``` | ||
|
|
||
| r[items.fn.c-variadic.lifetime] | ||
| The lifetime of a `VaList` is that of the function that created it. Hence, the `VaList` value can never outlive the function that created it. | ||
|
|
||
| r[items.fn.c-variadic.ffi-compatibility] | ||
| The rust [`VaList`] is ABI-compatible with the C `va_list` type. | ||
|
|
||
| r[items.fn.c-variadic.abi] | ||
| Only `extern "C"` and `extern "C-unwind"` function defintions can accept a variable argument list. | ||
|
|
||
| r[items.fn.c-variadic.safety] | ||
| Only `unsafe` functions can accept a variable argument list. | ||
|
|
||
| r[items.fn.c-variadic.async] | ||
| A c-variadic functions cannot be `async` | ||
|
|
||
| r[items.fn.c-variadic.const] | ||
| A c-variadic functions cannot be `const` | ||
|
|
||
| r[items.fn.c-variadic.platform-support] | ||
| Some ABIs do not support c-variadic function definitions. The compiler errors in this case. | ||
|
|
||
| ```text | ||
| error: the `bpfel` target does not support c-variadic functions | ||
| --> $DIR/not-supported.rs:23:31 | ||
| | | ||
| LL | unsafe extern "C" fn variadic(_: ...) {} | ||
| | ^^^^^^ | ||
| ``` | ||
|
|
||
| r[items.fn.c-variadic.dyn-compat] | ||
| When a trait method is c-variadic, the trait is no longer [dyn-compatible]. | ||
|
|
||
| r[items.fn.attributes] | ||
| ## Attributes on functions | ||
|
|
||
|
|
@@ -424,5 +500,7 @@ fn foo_oof(#[some_inert_attribute] arg: u8) { | |
| [associated function]: associated-items.md#associated-functions-and-methods | ||
| [implementation]: implementations.md | ||
| [value namespace]: ../names/namespaces.md | ||
| [variadic function]: external-blocks.md#variadic-functions | ||
| [c-variadic function]: external-blocks.md#variadic-functions | ||
| [`extern` block]: external-blocks.md | ||
| [`VaList`]: std::ffi::VaList | ||
| [dyn-compatible]: traits.md#dyn-compatibility | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this preserve what was meant
View changes since the review