1+++ 2title = "Limitations" 3description = "" 4weight = 10 5+++ 6 7C++ has excellent two-way compatibility with the C ABI, but there are some 8limitations you must observe to write C++ code which C code can call without 9marshalling at the ABI boundary: 10 111. A C++ function may not throw exceptions if it is safe to call from C, and 12so should always be marked `noexcept`. 13 142. A C++ function should be annotated with `extern "C"` to prevent its symbol 15being mangled, and thus give it the C rather than C++ ABI. 16 173. You cannot use overloading in your `extern "C"` functions. 18 194. You may only use types in your C++ function declaration for which these traits are both true: 20 - [`std::is_standard_layout_v<T>`](http://en.cppreference.com/w/cpp/types/is_standard_layout) 21 - [`std::is_trivially_copyable_v<T>`](http://en.cppreference.com/w/cpp/types/is_trivially_copyable) 22 23 (Note that `std::is_trivially_copyable_v<T>` requires trivial destruction, 24but NOT trivial construction. This means that C++ can do non-trivial construction 25of otherwise trivial types) 26 27--- 28 29The above is what the standard officially requires for *well defined* C and C++ interop. 30However, all of the three major compilers MSVC, GCC and clang are considerably more relaxed. 31In those three major compilers, "almost-standard-layout" C++ types work fine in C. 32 33"Almost-standard-layout" C++ types have these requirements: 34 351. No virtual functions or virtual base classes i.e. 36[`std::is_polymorphic_v<T>`](http://en.cppreference.com/w/cpp/types/is_polymorphic) 37must be false. This is because the vptrs offset the proper front of the data layout 38in an unknowable way to C. 392. Non-static data members of reference type appear to C as pointers. You 40must never supply from C to C++ a non-null pointer which is seen as a reference in C++. 413. C++ inheritance is seen in C data layout as if the most derived class has nested 42variables of the inherited types at the top, in order of inheritance. 434. Types with non-trivial destructors work fine so long as at least move construction 44and assignment is the same as 45copying bits like `memcpy()`. You just need to make sure instances of the type return 46to C++, and don't get orphaned in C. This was referred to in previous pages in this 47section as "move relocating" types. 48 49Experimental Outcome's support for being used from C does not meet the current strict 50requirements, and thus relies on the (very common) implementation defined behaviour just 51described (it is hoped that future C++ standards can relax the requirements to those 52just described). 53 54Specifically, proposed `status_code` is an almost-standard-layout type, 55and thus while it can't be returned from `extern "C"` functions as the compiler 56will complain, it is perfectly safe to return from C++ functions to C code on the 57three major compilers, as it is an "almost-standard-layout" C++ type if `T` is 58an "almost-standard-layout" C++ type. 59