Skip to content

Tracking issue for RFC 2137: Support defining C-compatible variadic functions in Rust (c_variadic) #44930

@aturon

Description

@aturon

This is a tracking issue for the RFC "Support defining C-compatible variadic functions in Rust" (rust-lang/rfcs#2137).

Steps:

Unresolved questions

  • It would be useful to have a miri implementation to nail down the semantics

We have a rough idea of how to support c-variadic arguments in miri in https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/c_variadic.20API.20and.20ABI/near/527283677:

beetrees: From my preliminary look at it, I think there'd need to be some hooks in InterpCx::init_stack_frame to allow Miri to handle the varargs.

RalfJ: ah, that part

RalfJ: okay I think that part might be best handled inside the interpreter

RalfJ: the intrinsics should be in miri

RalfJ: as in, add a new varargs field to struct Frame and initialize it in init_stack_frame as part of the general argument handling

RalfJ: that should probably be a Vec<MPlaceTy> that hold the values of these arguments (OpTy is not suited for long-term storage)

RalfJ: and then when popping a frame, they need to be freed alongside the other local variables

Resolved questions

Continuing bikeshed on the ... syntax

There has been no discussion of a different syntax in recent years.

When implementing this feature, we will need to determine whether the compiler can provide an appropriate lifetime that prevents a VaList from outliving its corresponding variadic function.

The compiler internally determines that lifetime, to make sure that a VaList<'_> does not outlive the function that created it.

Ensure that even when this gets stabilized for regular functions, it is still rejected on const fn.

This is tested in https://github.com/rust-lang/rust/blob/main/tests/ui/parser/variadic-ffi-semantic-restrictions.rs and gives the following error:

error: functions cannot be both `const` and C-variadic
  --> $DIR/variadic-ffi-semantic-restrictions.rs:33:1
   |
LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {}
   | ^^^^^ `const` because of this             ^^^^^^ C-variadic because of this

We reject c-variadic async functions in a similar way.

Issue #125431

The VaList definition introduced in #141980 circumvents this issue.

Issue #61275

This is an issue with c-variadic calls, not with c-variadic definitons.

Issue #141618

We have some forwards-compatible ideas for how to potentially add the ABI to the type in the future. That is only required if we want to allow calling c-variadic functions with a non-system ABI. Because C only allows using the system ABI for c-variadic calls, that is unlikely to come up in practice.

What exactly are the ABI requirements around variadic calls? What are the ABI compatibility rules? Do we have to be concerned about LLVM target features affecting variadic ABI?

Variadic calls using the system ABI do not impose any additional constraints. We already handle some ABI compatibility issues using target modifiers.

Implementation history

va_arg codegen

VaList and its layout

other

c-variadic adjacent

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-FFIArea: Foreign function interface (FFI)B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-c_variadic`#![feature(c_variadic)]`S-tracking-ready-to-stabilizeStatus: This is ready to stabilize; it may need a stabilization report and a PRT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions