extern "C"?

I know of an
 
extern "C"

keyword that prevents C++ from name-mangling to ease the interface of C++ code to other languages.

However, what I don't understand (and can't find reference online) is the exact semantics of this keyword. Why is it called `extern` like the keyword that is used to declare that function is defined in another compilation unit? And why is `C` written like a string literal? Is it historical?

Also, if there is `extern "C"`, is there `extern "ASM"` or something else out there?

Any input is welcome.
Keywords are reused where possible. Using new keywords makes it possible for the new keyword to clash with a symbol used in a program.

I think I've seen another language used with extern, but I must be wrong as I can't find any reference to it now.

Many common OS' you'll encounter these days are written in C. And that makes C the native system of the platform. As most programming languages will need to talk to the OS at sometime or another, they'll have to have to be able to call C functions. All this makes C is the de-facto standard.
there are some 'function types' which come in 2 main flavors and a couple of sub flavors if I recall, and they have to do with mixed languages and whether the caller or callee of a function is responsible for pushing and popping registers to restore the state after the function ends. Those are your _cdecl looking prefaces you see on functions sometimes.
The issue is that C has a fairly standardized “binary” interface — how things are structured in compiled objects (on your platform).

C++ does not — the standards committee wants to leave that up to compiler implementations. Part of the result is the (necessary) name mangling. It runs much, much deeper down the rabbit hole than that, though.

In any case, extern "C" is used to prefix declarations that should be emitted using C’s binary interface.

For reference, you can learn just about everything you need (and probably want) to know about it from https://en.cppreference.com/w/cpp/keyword/extern.

Hope this helps.
The issue is that C has a fairly standardized “binary” interface [...] C++ does not — the standards committee wants to leave that up to compiler implementations

There is no standard ABI for either C++ or C. It is up to compiler implementations for both languages. In practice, compiler implementors follow platform standards for each target platform, such as ARM ABI or Power ABI or SysV ABI (non-Windows x86/x64) or Microsoft x86/x64 ABI, each of those defines the rules for both C++ and C.

if there is `extern "C"`, is there `extern "ASM"` or something else out there?

every compiler also supports extern "C++". Beyond C++ and C, it's up to individual compilers. A bit of stackoverflow surfing suggests there exist(ed) extern "Pascal", extern "FORTRAN", extern "COBOL", extern "PLI", in now-obsolete and obscure compilers.
[what are] the exact semantics of this keyword
Just put extern "C" before the declaration (and definition if applicable) of the function.

There are some other non-standard extensions, for example, pascal to indicate PASCAL calling conventions.
I tried to look it up and some are saying extern C is naming conventions (mangle or not) and cdecl (etc) are calling conventions (call stack management & friends). It sounds like you guys are saying extern c is doing both, though (?).
Yes. extern "C" says "do the needful to let this program call this function if it was created by the C compiler. That means name mangling, calling conventions, whatever.
There is no standard ABI for either C++ or C. ... In practice, compiler implementors follow platform standards

So... C has a fairly standardized “binary” interface ... (on your platform).
I did not say that C mandated the standard.

That means name mangling, calling conventions, whatever.

It means default calling conventions.

The calling convention remains a separate issue, and is — with rare exception — a Windows thing. (AFAIK.)
Duthomhas wrote:
So... C has a fairly standardized “binary” interface ... (on your platform).
I did not say that C mandated the standard.

You implied that there is a difference between C and C++ in that respect.
My understanding was that while neither C nor C++ have any standard ABI, C has more of a "de facto" standard on a given platform, so it will be the same across VS, GCC, clang, etc, but in C++ this is even less likely, especially due to name overloading and v-tables. Certainly I could be wrong.
Last edited on
It's the same "de-facto" standard for both languages on a given platrom.
For example, the one I know best is non-Windows x64 ABI, defined here: https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
(VS has a totally different standard for both, even the C calling convention is nothing like what Linux uses)
Last edited on
You implied that there is a difference between C and C++ in that respect.

Indeed I did.

You must be specific with your compiler to tell it not to do C++ stuff to things with the binary interface.

It's the same "de-facto" standard for both languages on a given platrom.

No it’s not. The de-facto C standard is a basis upon which different C++ implementations build, with absolutely no effort to synchronize as yet.

This is the reason that it is still a nightmare to try to build portable C++ DLLs. (And by "portable" I mean "usable by other languages and/or systems on the same platform.)

(VS has a totally different standard for both, even the C calling convention is nothing like what Linux uses)

That’s kind of the point.

POSIX sets a good basis that has helped Linux be much more uniform in terms of ABI and the like than has ever existed on Windows.

On Windows, you’re in a Wild West shootout, and the bullets are still flying. VS is not going to change the way it does things — there is absolutely too much money sitting on legacy support.

And GCC is too stubborn to consider that its design isn’t necessarily the One True Way. Fortunately, even GCC ports must interface with native Microsoft stuff, so as long as you frob the compiler correctly you can still get ABI compatibility on Windows.

Other compiler systems vary.
The de-facto C standard is a basis upon which different C++ implementations build, with absolutely no effort to synchronize as yet.

maybe that's how it was in the 1980s, but it's 2020 now. C++ and C ABIs are both defined by the same document for each target architecture.
Heh, shows my age. Remember, I was programming Windows back when it was called "DOS", LOL.

Regardless of anything else, anything that appears on a PC box must appear in one of several formats. Any standards documents (that I admit I didn't know existed these days) for ABI are necessarily built on preexisting conditions.

C++ stuff, AFAIK, is still inoperable with C stuff and between compilers. Let me know if that has changed...

I'm really not more than a tinkerer now...
Topic archived. No new replies allowed.