...
A special instance of this guidance involves non-C++ code compiled by a different compiler, such as C standard library implementations that are exposed via the C++ standard library. C standard library functions are exposed with C++ signatures, and the type system frequently assists in ensuring that types match appropriately. This disallows passing a pointer to a C++ object to a function expecting a char *
without additional work to suppress the type mismatch. However, some C standard library functions accept a void *
, for which any C++ pointer type will suffice. Passing a pointer to a nonstandard-layout type in this situation results in indeterminate behavior, as it depends on the behavior of the other language as well as the layout of the given object.
Only pass a nonstandard-layout type object across execution boundaries when both sides of the execution boundary adhere to the same ABI. For instance, if the same version of the compiler is used to compile both sides of the execution boundary, or if the compiler used to compile both sides of the execution boundary is ABI-compatible across multiple versions, or if the differing compilers used document that they adhere to the same ABI.
Noncompliant Code Example
...
Code Block | ||||
---|---|---|---|---|
| ||||
struct B { int i, j; }; struct D : B { float f; }; void f(D *d) { struct { int i, j; float f; } temp; temp.i = d->i; temp.j = d->j; temp.f = d->f; extern "Fortran" void func(void *); func(&temp); } |
Exceptions
...
Risk Assessment
The effects of passing objects of nonstandard-layout type across execution boundaries depends on what operations are performed on the object within the callee as well as what subsequent operations are performed on the object from the caller, and can range from correct or benign behavior to undefined behavior.
...