Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Language Linkage

Status
Not open for further replies.

electroRF

Member
Hi,

I learned that C compiler converts a function's prototype/definition to a binary format by the function name Only,

while C++ compiler converts a function's prototype/ definition to a binary format by its function name + arguments types/quantity. (that's why functions overloading is feasible in C++)

Then, it was said that to enable calling C compiled function from C++ code, one should use the extern "C" directive.

What does it mean?

why can't C++ compiler just compile all these function in both CPP and C source files?

Or is the above talking on a case where C++ Compiler is given C Object files, and not C Source files.


for example, when I write this function, without using extern "C" on printf(..), I don't get linkage error.

How come?

(I use Visual Studio C++ Compiler)

C:
#include <stdio.h>

int main()
{
printf("hello, is it me you're looking for");
return 0;
}
 
Last edited:
With dynamic loading function may reside in a different file which could be written by different people, such as Windows DLL, and the link gets established only in the run time.
 
Hi Northguy,
Thank you.

I actually did not manage to understand your comment.

Say that functions are written in different files by different people.

Now all the functions and files are compiled by C++ Compiler.

What's wrong with that?
 
Imagine you write a library that is supposed to be used by other people who use dozens of different languages. You do not want to use C++ name mangling on your functions because other people will have a hard time accessing your functions.
 
But if the C++ compiler use name mangling on both the calls to the functions prototypes and functions definitions, so why should there be a problem that a prototype will miss definition?

I mean, say the printf C function, what is wrong with having the C++ compiler, compiling both its prototype and definition?
 
Last edited:
Compiler only creates object files. Object files only contain a name of the function and where to find it. C++ changes the name of the function to reflect the definition. Another object file may need a reference to thia function. Linker (or dynamic loader) tries to tie these object files together and to do that the names must much. If they're not mangled in both places, it'll successed. If they're mangled in one place, but not the other, it'll not succeed.

So, if you biuld everything with C++, it links against CPP libraries, everything is mangled everywhere, you're Ok.

If you build everything with C, it links agains C libraries, nothing is mangled, you're Ok.

If you get a C library, which is not mangled, and want to access from C++ code, the C function name is not mangled, but C++ name is. They won't link. Therefore, in this case, you need to tell C++ compiler to use the unmangled name.
 
Compiler only creates object files. Object files only contain a name of the function and where to find it. C++ changes the name of the function to reflect the definition. Another object file may need a reference to thia function. Linker (or dynamic loader) tries to tie these object files together and to do that the names must much. If they're not mangled in both places, it'll successed. If they're mangled in one place, but not the other, it'll not succeed.

So, if you biuld everything with C++, it links against CPP libraries, everything is mangled everywhere, you're Ok.

If you build everything with C, it links agains C libraries, nothing is mangled, you're Ok.

If you get a C library, which is not mangled, and want to access from C++ code, the C function name is not mangled, but C++ name is. They won't link. Therefore, in this case, you need to tell C++ compiler to use the unmangled name.

NorthGuy,
Thank you SO much :) Awesome explanation!

Is it correct to say that we'd need the extern "C" statement only in cases where some of the Object Files were compiled by C Compiler, and the other by C++ Compiler?
(i.e. if all Source Files are compiled by C++ compiler, then there's no need for extern "C", right?)

I'd like to make it clear please:
NorthGuy said:
If you get a C library, which is not mangled, and want to access from C++ code, the C function name is not mangled, but C++ name is. They won't link.

by "getting a C library", do you mean getting an Object File of that C Library, and NOT the Source + Header Files of that C library?

As if we get the source + header files of this C library, then everything could be compiled by C++ compiler, and the C functions will link.
 
Is it correct to say that we'd need the extern "C" statement only in cases where some of the Object Files were compiled by C Compiler, and the other by C++ Compiler?
(i.e. if all Source Files are compiled by C++ compiler, then there's no need for extern "C", right?)

Yes, if you use standard header files and libraries (which you do if you didn't change anything), you do not need to worry about mangling.

by "getting a C library", do you mean getting an Object File of that C Library, and NOT the Source + Header Files of that C library?

As if we get the source + header files of this C library, then everything could be compiled by C++ compiler, and the C functions will link.

If you get someone else's library, it'll come with header files. Most likely, these header files will be ok for C++. Header files are for the compiler. Library files (sort of object files) are for linker. If there's a problem with header files, you get a compiler error. If there's a problem with library files, you get a linker error.
 
Thank you NorthGuy! :)

I didn't manage to find a link of how a library is created, you happen to know a good one?

So actually, if a lib file was compiled in C, then its header MUST be inside an extern "C" { /* functions prototypes */ } block?
 
I didn't manage to find a link of how a library is created, you happen to know a good one?

So actually, if a lib file was compiled in C, then its header MUST be inside an extern "C" { /* functions prototypes */ } block?

It depends on your compiler/linker. You use a command line switch to tell it to create a library or you tick a box in IDE. You can also choose static or dynamic library.

You normally don't write headers, but get them along with the library. Most likely extern "C" will be already there (conditional for C++ compiler) one way or the other. So, you don't need to worry about.

If you, for whatever reason, create a header file by yourself, you need to look if the names in the library are mangled, and if they're not (most likely) then use extern "C". You also need to work out correct calling conventions, and, of course, parameters to pass to the functions.
 
I always use this kind of template for my C header files:
C:
/* Multiple inclusion #ifdef (a.k.a. "include guard") */
#ifndef TEMPLATE_H
#define TEMPLATE_H

/* Preprocessor directives like #include and #define */

/* C/C++ #ifdef */
#ifdef _cplusplus
extern "C" {
#endif

/* Function prototypes etc. */

/* C/C++ #ifdef */
#ifdef _cplusplus
}
#endif

#endif /* Multiple inclusion #ifdef */
 
See. If MisterT would send you his library with the headers, you wouldn't have any problems.

I used to sell a DLL in 90-s. I looked at the header, and look what I found in front of every function:

C:
#ifdef __cplusplus
extern "C"
#endif
WORD WINAPI ...
 
Thank you guys! :)

You helped me out a lot!

NorthGuy,
Regarding if Mister T would send me his library and the headers.

If Mister T would send me his source code and headers, then I could remove the extern "C" from his headers, and compile everything in the C++ compiler, and that way also his C functions will be mangled in his source codes and in his headers, and all would work, right?
 
If Mister T would send me his source code and headers, then I could remove the extern "C" from his headers, and compile everything in the C++ compiler, and that way also his C functions will be mangled in his source codes and in his headers, and all would work, right?

Here's the rub. He wouldn't give you his source code, only the binary library and headers.
 
yes i know :)

I'm just trying to understand the meaning of the extern "C", thanks why I asked.

i.e. to understand when it's needed (as in the lib / DLL example), and what it is not needed.
 
It's needed when you do not want your names mangled:

1. You have a library with non-mangled names that you want to use

or

2. You create your own library and you want non-mangled names in there so that it could be used outside of C++
 
Status
Not open for further replies.

Latest threads

Back
Top