On 8/24/2010 7:55 AM, Stanisław Findeisen wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2010-08-24 16:12, Thomas Hruska wrote:
>> On 8/24/2010 4:50 AM, Stanisław Findeisen wrote:
>>> ======================================================================
>>> If you are including a C header file that isn't provided by the system,
>>> you may need to wrap the #include line in an extern "C" { /*...*/ }
>>> construct. This tells the C++ compiler that the functions declared in
>>> the header file are C functions.
>>>
>>> http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3
>>> ======================================================================
>>>
>>> 1. What if I don't wrap them? Is it possible to have runtime errors
>>> because of that? I understand linker errors are possible.
>>
>> This is just addressing name mangling issues. Look up "name mangling"
>> on Google.
>
> What about calling conventions?
You mean like _stdcall and _cdecl? Those only affect how parameters are
passed and values are returned. They also have nothing to do with name
mangling which is what extern "C" is for.
>>> 2. When do you think this wrapping is not needed, i.e. what do you think
>>> "provided by the system" was meant to mean? Parashift.com author gives
>>> <cstdio> as an example, but what about POSIX headers like<pthread.h> or
>>> <sys/socket.h>? Do you need to wrap them in extern "C" in portable code?
>>
>> Those are provided by the system. The author is referring to
>> third-party code not supplied by the vendor directly.
>
> What's the difference??
By third-party, I generally mean anything that is not ubiquitous. POSIX
is basically ubiquitous on *NIX.
>>> ======================================================================
>>> [32.6] How can I create a C++ function f(int,char,float) that is
>>> callable by my C code?
>>>
>>> The C++ compiler must know that f(int,char,float) is to be called by a C
>>> compiler using the extern "C" construct [...]
>>>
>>> http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.6
>>> ======================================================================
>>>
>>> ======================================================================
>>> [...] static member functions do not require an actual object to be
>>> invoked, so pointers-to-static-member-functions are usually
>>> type-compatible with regular pointers-to-functions. However, although it
>>> probably works on most compilers, it actually would have to be an extern
>>> "C" non-member function to be correct, since "C linkage" doesn't only
>>> cover things like name mangling, but also calling conventions, which
>>> might be different between C and C++.
>>>
>>> http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
>>> ======================================================================
>>>
>>> 3. Is it possible to have runtime errors if you don't use extern "C" in
>>> this case? I think YES?
>>
>> Only if name mangling gets screwed up really badly somehow.
>
> What about calling conventions?
Again, two separate things. You would have to compile against two
different calling conventions to experience issues. No one is going to
write a screwy header like that. Plus linkers wouldn't find a match
when scanning the object files so linking will fail (i.e. you wouldn't
get as far as runtime errors).
>> The linker
>> is usually pretty good about preventing such things. The runtime error
>> would almost always be the inability to load a module (.dll/.so) because
>> one or more of the exports won't resolve dynamically and then the whole
>> program would fail to load as a result. That is, the OS won't load the
>> program in the first place due to dependency issues. However, as I
>> said, the linker is pretty good about preventing such problems.
>>
>> I've never had compilation problems like that where the same compiler
>> suite is used for all the components being built.
>
> Maybe, but I am asking about the standard.
The Standard is, honestly, outdated. It was designed for output to a
line printer and input from punch cards. That's a joke, BTW.
But the point is somewhat relevant. POSIX is its own Standard. And
interoperability within POSIX and C/C++ has a pretty high priority in
the open source community. You will be hard-pressed to find a modern
POSIX-compliant implementation that had name-mangling or calling
convention issues. Again, the linker would stop you.
>>> 4. What effect does extern "C" have on C++ function in this case? It's
>>> about generating machine code of the function itself, right? No wrapper?
>>> So when you call this C++ function from within C++ code (from the same
>>> or another translation unit), the C calling convention should be used?
>>
>> Not sure what you are asking here. I think you are just confused at
>> this point. I know the feeling.
>
> I am asking about the function calling conventions. For from
> http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2
> I've learned that in C and C++ they might different. So if you want a C
> code to call your C++ function, you have to make that function
> compatible with C calling convention. Otherwise you can get a runtime
> BANG. Right?
Yes, but you can specify the calling convention. I see this as a
non-issue. The linker will stop you in almost all cases with the
inability to find the correct exported symbol.
> However the question is: given an architecture and a language (C or C++)
> does there exist exactly 1 standard calling convention??
No. _stdcall, _cdecl, _pascal, and a couple others are the most common
calling conventions. Again, the linker usually does a pretty good job here.
If you can't tell, I rely heavily on the compiler and linker to catch a
lot of issues. They do a good job - that is what they are designed to do.
--
Thomas Hruska
CubicleSoft President
Barebones CMS is a high-performance, open source content management
system for web developers operating in a team environment.
An open source CubicleSoft initiative.
Your choice of a MIT or LGPL license.
http://barebonescms.com/