There is nothing in any standard that requires calling conventions in C and C ++ to be the same in this compiler, except that the declared C ++ extern "C"
function must be called with the same call as the C function .
Therefore, for pointer-to-function and pointer-to-function-with-C-relationship with the same parameters and return type, there are different types. When a function is called, the compiler can learn from the type to which the call calls the call, if they are different.
In practice, I donโt think I have ever consciously dealt with an example that uses an incompatible calling convention between free functions with and without C. Typically, a C ++ implementation accepts its calling convention from the ABI system, which it plans to run in order to create related objects (executable files and libraries) that other users of the system can understand from an ABI point of view.
This is not required - the standard does not care if there is an ABI system, and the system usually does not care about how calls are made in a stand-alone executable file [*]. It is simply wise to do this if there is no extraordinary reason. The ABI system in this system may or may not mention C ++ - if not then the C ++ implementation itself does not apply to functions that are not related to C-connection, but, as I said, it is usually reasonable to create functions that could C -link uses the same calling convention as if they had a C-link.
I say "incompatible" and not "different" because of course there are some things that are not mentioned in the C calling convention, but should be specified in the C ++ calling convention. For example, how to pass a member pointer function. It is possible that this is not related to the ABI system, and therefore remains for the implementation of C ++. The reason for this is to leave the implementation of the member-pointer function to the implementation of C ++, and not because the ABI system does what the manufacturer considers the work of the C ++ compiler.
With defiant convention aside, note that a name change inevitably differs between a free function with or without C-link. The reason is that changing the C ++ language name should include parameter types (due to function overload), while a type C name failure should not (due to extern function declarations with undefined parameters).
[*] Although I have seen examples where using the "wrong" calling convention breaks things. ISTR is a Windows mobile device, where if you formatted the stack differently than expected from the OS, then certain hardware exceptions will throw the device out because the OS tried to restore the stack of the calling thread and couldnโt. Therefore, at least on this version of the OS, probably around 2005, if you want the OS diagnostics to work, you had to use internal Windows calls. Or in any case, the portion of the calling convention related to the stack frame format. Of course, this was a complete error, but I donโt know if we could fix it properly by setting our own handlers for hardware exceptions, instead of going around them without causing exceptions in the first place. This meant that the user mode process could trivially remove the OS with a stack overflow, although it was more difficult to debug our code than on other Windows. Therefore, we blamed the OS a little.