Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Reverted from v. 2

...

Some compilers do conform to the C++ Standard, but only in their strictest conformance mode, such as EDG 4.11. This implementation divergence from the C++ Standard is a matter of practical design trade-offs. Compilers are only required to support the "C" and "C++" language linkages, and interoperability between these two languages often does not require significant code generation differences beyond mangling of function types for most common architectures such as x86, x86-64, and ARM. There are extant Standard Template Library implementations for which language linkage specifications being correctly implemented as part of the function type would break existing code on common platforms where the language linkage has no effect on the runtime implementation of a function call.

It is acceptable to call a function with a mismatched language linkage when the combination of language linkage specifications, runtime platform, and compiler implementation result in no effect on runtime behavior of the function call. For instance, the following code is permissible when compiled with Microsoft Visual Studio 2015 for x86, despite the lambda function call operator implicitly converting to a function pointer type with C++ language linkage, while qsort() expects a function pointer with C language linkage.

Code Block
#include <cstdlib>
 
void f(int *int_list, size_t count) {
  std::qsort(int_list, count, sizeof(int),
             [](const void *lhs, const void *rhs) -> int {
               return reinterpret_cast<const int *>(lhs) <
                      reinterpret_cast<const int *>(rhs);
             });
}

Noncompliant Code Example

In this noncompliant code example, the call_java_fn_ptr() function expects to receive a function pointer with "java" language linkage because that function pointer will be used by a Java interpreter to call back into the C++ code. However, the function is given a pointer with "C++" language linkage instead, resulting in undefined behavior when the interpreter attempts to call the function pointer. This code should be ill-formed because the type of callback_func() is different than the type java_callback, but due to common implementation divergence from the C++ Standard, some compilers may incorrectly accept this code without issuing a diagnostic.

...

Code Block
bgColor#ccccff
langcpp
extern "java" typedef void (*java_callback)(int);

extern void call_java_fn_ptr(java_callback callback);
extern "java" void callback_func(int);

void f() {
  call_java_fn_ptr(callback_func);
}

Exceptions

EXP64-CPP:EX1 It is acceptable to call a function with a mismatched language linkage when the combination of language linkage specifications, runtime platform, and compiler implementation result in no effect on runtime behavior of the function call. For instance, the following code is permissible when compiled with Microsoft Visual Studio 2015 for x86, despite the lambda function call operator implicitly converting to a function pointer type with C++ language linkage, while qsort() expects a function pointer with C language linkage.

Code Block
#include <cstdlib>
 
void f(int *int_list, size_t count) {
  std::qsort(int_list, count, sizeof(int),
             [](const void *lhs, const void *rhs) -> int {
               return reinterpret_cast<const int *>(lhs) <
                      reinterpret_cast<const int *>(rhs);
             });
}

Risk Assessment

Mismatched language linkage specifications generally do not create exploitable security vulnerabilities between the C and C++ language linkages. However, other language linkages exist where the undefined behavior is more likely to result in abnormal program execution, including exploitable vulnerabilities.

...