C/C++ calling convention

  • Thread starter StanisÅ‚aw Findeisen
  • Start date
J

James Kanze

On Aug 25, 4:18 pm, Stanis³aw Findeisen <[email protected]> wrote:

[...]
Any compiler provides you with a way to specify what calling
convention you want from a list of calling conventions chosen by that
compiler (look for e.g. __cdecl).

On most machines, there is only one reasonable way to pass
arguments when calling a function, and most compilers do not
need or have extensions to specify many different calling
conventions---they use the standard ``extern "language"''.
 
J

James Kanze

simply:
C doesn't have vtables (or, at least, compiler generated ones);
in the C++ case, they are structures.
effectively, then, vtables are part of the ABI, but are not part of the
calling convention.

The calling convention and the ABI are basically two words for
the same thing.

(On rereading it, I find my phrase a bit ambiguous. The "Except
on Intel" should apply to what I've written. On architectures
other than Intel, the first argument (or the first n
arguments---5 on a Sparc) are passed in registers.
not in cdecl or stdcall...
cdecl and stdcall tend to pass *everything* on the stack.

What is cdecl or stdcall? They don't exist on most compilers
I've used. And as I said, except on Intel, the first
n arguments are normally passed in registers.
something can easily "work" in many cases, but still not be
"safe" in a portability sense.

For what definition of "safe"? You define the constraints of
your library (usually, by specifying what options must be used
when compiling code which links to it). If the user conforms to
those constraints, there's no problem.
if one can do it, they can declare that it "works on most
platforms of interest", which may exclude some edge cases (for
example, most PC or server targetted code will not work on
embedded systems, ...).

Well, obviously, you can't write a portable dll which will work
on a system which doesn't have dlls.
as for C++ ABI's, the main issue is that MSVC and MinGW on
Windows use different C++ ABI's, and so if one wants to
support use of either compiler (with pre-existing binary
code), it is best to avoid using C++ as a basis for API's.

VC++ and g++ both change the C++ ABI depending on compiler
options. So what else is new? Your client code must be
compiled with the same compiler (or one which guarantees binary
compatibility), using the same options.
other compilers tend to have other ABI's as well, and so this
leaves the C ABI as the "most portable" option.

I think we're talking at cross purposes. For binary
compatibility, yes, C is the only real solution. I was talking
about source code compatilibity.
using 'extern "C"' generally works without issue though, so
long as one fully adheres to C restrictions at the API level.
this is the default behavior. one has to tell it to do
otherwise, but then it uses 'msvcr80.dll', which has to be
supplied manually on WinXP.

I'm not aware of any "default" behavior. When I type in "cl
/help", it tells me to chose one of /MT, /MTd, /MD or /MDd
(indirectly, at least). And every Windows application I've
worked on uses /MD or /MDd, which doesn't cause any problems.
yes, but this is not necessarily a desirable feature, and is
actually kind of annoying sometime...

It depends on what you're doing. If you're supporting third
party plugins, you'd like them to be as isolated as possible.
 
I

Ian Collins

On 08/25/10 02:50 PM, BGB / cr88192 wrote:
[...]
similarly, it is not really "safe" to use C++-based APIs
across library boundaries, nor for that matter to pass
memory or file references between DLL's (this leads to "fun"
sometimes...).
That is very platform specific. Those restrictions don't
apply to Unix or Unix like systems.

Which part of his statement are you referring to?

Most of it.
It's not safe
to use C++ based APIs (with std::string, etc.) between code
compiled with different compiler options, with the same
compiler.

He wasn't specific, as you are. Build everything with the same compiler
and options and there aren't any problems using C++ based APIs.
And there's no problem passing memory or file
references between dynamically loaded object files on any of the
systems I've worked on, Windows or Unix. (We do it all the time
under Windows, here, and we did it regularly under Solaris and
Linux where I was before.)

Quite. I've never heard of that restriction.
 
J

Joshua Maurice

Quite.  I've never heard of that restriction.

I think this is partially from older windows compilers which had the
option to compile the C standard library statically into a dll. When
this was done, each statically linked c standard library had its own
heap (and other resource managers), so you could not "new" some memory
in one dll and "delete" it in another. This problem is neatly solved
nowadays by dynamically linking to the C standard library. Didn't some
of the newer versions of Microsoft's visual studios devenv.exe remove
C std lib static linking as an option entirely? I guess Microsoft is
playing slowpoke catchup with good practice as always.
 
I

Ian Collins

not in cdecl or stdcall...
cdecl and stdcall tend to pass *everything* on the stack.
Eh?

64-bit Windows and Linux pass arguments in registers.

That is because that's what the AMD64 ABI specifies.
fastcall also uses registers, but fastcall is rarely the default convention
(usually it has to be specified manually).

fastcall?
 
B

BGB / cr88192

Quite. I've never heard of that restriction.

<--
I think this is partially from older windows compilers which had the
option to compile the C standard library statically into a dll. When
this was done, each statically linked c standard library had its own
heap (and other resource managers), so you could not "new" some memory
in one dll and "delete" it in another. This problem is neatly solved
nowadays by dynamically linking to the C standard library. Didn't some
of the newer versions of Microsoft's visual studios devenv.exe remove
C std lib static linking as an option entirely? I guess Microsoft is
playing slowpoke catchup with good practice as always.
-->

apparently, AFAICT, they had reverted to statically-linking the thing, or at
least this is my experience.
why? I don't know...

note that I am using the Platform SDK v6.1 on WinXP, so this is not exactly
an old version of MSVC.

for some things, have also been using Visual Studio 2008, which uses v6.0A.
 
B

BGB / cr88192

On Aug 25, 4:18 pm, Stanis³aw Findeisen <[email protected]> wrote:

[...]
Any compiler provides you with a way to specify what calling
convention you want from a list of calling conventions chosen by that
compiler (look for e.g. __cdecl).

<--
On most machines, there is only one reasonable way to pass
arguments when calling a function, and most compilers do not
need or have extensions to specify many different calling
conventions---they use the standard ``extern "language"''.
-->

well, if one excludes 32 bit Windows, where in practice 4 calling
conventions are commonly used:
cdecl; stdcall; fastcall; and thiscall (modified cdecl).

in most cases, fastcall can be ignored (it is almost never used for external
linkage AFAICT), and thiscall can simply be regarded as a special case of
cdecl.


this is a major reason for modifier tags like WINAPI and similar: they wrap
the calling convention keywords.


on 64-bit Windows, there is a single calling convention (Win64);
on 64-bit Linux and OSX, there is a single calling convention (AMD64);

on 32-bit Linux, in practice pretty much everyone just uses cdecl...


IIRC, MS-DOS was a mess though, with many compilers doing things
differently, so code from one compiler would not normally link correctly
with code produced by another. 32-bit Windows mostly stabilized the calling
convention and object-file format mess (nearly everything is either cdecl or
stdcall, and uses COFF...).
 
B

BGB / cr88192

Ian Collins said:

yep.

usually, cdecl functions go like:
push ebp
mov ebp, esp
sub esp, <something>
....
mov esp, ebp ;or sometimes "add esp, <something>"
pop ebp
ret

within the function, (except when returning structs):
[ebp+8] ;arg0
[ebp+12] ;arg1
[ebp+16] ;arg2
[ebp+20] ;arg3
....

stdcall functions are similar, except they tend to use "ret <argsize>" vs
"ret", which also removes arguments from the stack.

cdecl has another name, like "SysV i386 ABI" or similar.
stdcall was apparently created by MS, and I don't know of another name for
it.


struct returning tended to be not entirely consistent between compilers, but
just assuming the "generic" way of returning structs (passing an extra
hidden argument to tell the called function where to put the struct) seems
to work for the most part.

That is because that's what the AMD64 ABI specifies.

yep.



fastcall?

it was another convention used by MS and others, where the idea was that the
first some-odd arguments would be passed in registers rather than on the
stack, but it was not well standardized.

http://en.wikipedia.org/wiki/Fastcall

MS's variant (the most common one AFAIK) used ECX and EDX for argument
passing.
 
G

Goran Pusic

it was another convention used by MS and others, where the idea was that the
first some-odd arguments would be passed in registers rather than on the
stack, but it was not well standardized.

http://en.wikipedia.org/wiki/Fastcall

MS's variant (the most common one AFAIK) used ECX and EDX for argument
passing.

Heh, a blast from the past! Yes, Borland's fastcall was different from
MS's fastcall.

There's no "standardization" here, jut convention.

Goran.
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message
Any compiler provides you with a way to specify what calling
convention you want from a list of calling conventions chosen by that
compiler (look for e.g. __cdecl).
<--
On most machines, there is only one reasonable way to pass
arguments when calling a function, and most compilers do not
need or have extensions to specify many different calling
conventions---they use the standard ``extern "language"''.
-->
well, if one excludes 32 bit Windows, where in practice 4 calling
conventions are commonly used:
cdecl; stdcall; fastcall; and thiscall (modified cdecl).

By "most machines", I meant most types of machines. Windows is
a bit of an exception, although even here, it's only really an
exception when using VC++, who decided not to use the standard
mechanism. (cdecl and stdcall resolve to ``extern "C"'' and
``extern "Pascal"'', I think. And thiscall is an extension of
cdecl, only relevant for ``extern "C++"''. The language also
allows a compiler to define something like ``extern "Fast"'',
although why one would use a slow call when a fast one is
available is beyond me.)
in most cases, fastcall can be ignored (it is almost never
used for external linkage AFAICT), and thiscall can simply be
regarded as a special case of cdecl.
this is a major reason for modifier tags like WINAPI and
similar: they wrap the calling convention keywords.
on 64-bit Windows, there is a single calling convention (Win64);
on 64-bit Linux and OSX, there is a single calling convention (AMD64);

As is the case under Solaris, HP/UX and AIX. And probably every
other system around.
on 32-bit Linux, in practice pretty much everyone just uses
cdecl...

On 32-bit Linux, I've never used anything.
IIRC, MS-DOS was a mess though, with many compilers doing
things differently, so code from one compiler would not
normally link correctly with code produced by another.

Yes and no. All of the C compilers I tried did the same thing.
All of the C++ compilers were different. But that's the case
almost universally today as well.
32-bit Windows mostly stabilized the calling convention and
object-file format mess (nearly everything is either cdecl or
stdcall, and uses COFF...).

Windows defines an ABI for C, I think (which it uses when
calling into system DLL's).
 
G

Goran Pusic

Windows defines an ABI for C, I think (which it uses when
calling into system DLL's).

Hey! That should be "Windows defines an ABI, full stop". :)

Why "for C" part? Many self-respecting toolchains on windows,
including some completely oblivious to C in particular, implement
whatever is necessary to be able to call into system without going
over anything C. Old VB6- does that, FreePascal/Delphi do it, of
course .NET does it...

In fact, I'd go as far as to say that any given system effectively has
a language-agnostic ABI (but they all lean towards simplicity of C).

Goran.
 
B

Bo Persson

Goran said:
Hey! That should be "Windows defines an ABI, full stop". :)

Why "for C" part? Many self-respecting toolchains on windows,
including some completely oblivious to C in particular, implement
whatever is necessary to be able to call into system without going
over anything C. Old VB6- does that, FreePascal/Delphi do it, of
course .NET does it...

In fact, I'd go as far as to say that any given system effectively
has a language-agnostic ABI (but they all lean towards simplicity
of C).

The fact that MS used their C compiler when creating the API might
have had an influence. :)


Bo Persson
 
J

James Kanze

Hey! That should be "Windows defines an ABI, full stop". :)
Why "for C" part?

Because the ABI is defined in C.
Many self-respecting toolchains on windows, including some
completely oblivious to C in particular, implement whatever is
necessary to be able to call into system without going over
anything C.

Because both the Windows and the Unix system interfaces are
defined in C, most languages support calling into C. Most
languages also have their own libraries, which mask the C part.
You can write code in just about any language without ever using
the Windows ABI.
Old VB6- does that, FreePascal/Delphi do it, of
course .NET does it...
In fact, I'd go as far as to say that any given system
effectively has a language-agnostic ABI (but they all lean
towards simplicity of C).

That used to be true in the distant past, but not today.
 
B

BGB / cr88192

"James Kanze" <[email protected]> wrote in message
Any compiler provides you with a way to specify what calling
convention you want from a list of calling conventions chosen by that
compiler (look for e.g. __cdecl).
<--
On most machines, there is only one reasonable way to pass
arguments when calling a function, and most compilers do not
need or have extensions to specify many different calling
conventions---they use the standard ``extern "language"''.
-->
well, if one excludes 32 bit Windows, where in practice 4 calling
conventions are commonly used:
cdecl; stdcall; fastcall; and thiscall (modified cdecl).

<--
By "most machines", I meant most types of machines. Windows is
a bit of an exception, although even here, it's only really an
exception when using VC++, who decided not to use the standard
mechanism. (cdecl and stdcall resolve to ``extern "C"'' and
``extern "Pascal"'', I think. And thiscall is an extension of
cdecl, only relevant for ``extern "C++"''. The language also
allows a compiler to define something like ``extern "Fast"'',
although why one would use a slow call when a fast one is
available is beyond me.)
-->

yeah.

most compilers I have seen have used the "__callconv" type keywords,
although granted my experience is mostly limited to Windows (where this
convention would likely be default as MS uses it), and Linux (where
generally there is only a single calling convention in use, hence no real
need to use it...).

this notation makes a little more sense IMO than the 'extern "lang" '
notation in many cases, as it allows defining the calling convention of
function pointers, ... which the former can't do effectively, however, the
'extern "lang" ' notation does have the usefulness that it can be applied to
an entire block of definitions, rather than having to be endlessly repeated
for each declaration.

hence:
void (__stdcall *foo)(int x, double y);

and:
extern "C"
{
...
}

in most cases, fastcall can be ignored (it is almost never
used for external linkage AFAICT), and thiscall can simply be
regarded as a special case of cdecl.
this is a major reason for modifier tags like WINAPI and
similar: they wrap the calling convention keywords.
on 64-bit Windows, there is a single calling convention (Win64);
on 64-bit Linux and OSX, there is a single calling convention (AMD64);

<--
As is the case under Solaris, HP/UX and AIX. And probably every
other system around.
-->

most non-Windows systems on x86-64 AFAIK use AMD64.

admittedly, I personally like Win64's design a little more, as AMD64 seems a
bit complicated and over-engineered and likely to actually reduce
performance slightly in common use cases vs Win64's design.

on 32-bit Linux, in practice pretty much everyone just uses
cdecl...

<--
On 32-bit Linux, I've never used anything.
-->

on 32-bit Linux, there is only a single calling convention in single use, so
no one needs to...
doesn't mean the calling convention is not there, only that it is not needed
to specify it.

IIRC, MS-DOS was a mess though, with many compilers doing
things differently, so code from one compiler would not
normally link correctly with code produced by another.

<--
Yes and no. All of the C compilers I tried did the same thing.
All of the C++ compilers were different. But that's the case
almost universally today as well.
-->

there were differences.
many C compilers used OMF (as the object format), and some used others
(including COFF, but this was typically for DPMI-based compilers, as well as
I think I remember there being 32-bit OMF, ...);
there were a few others as well IIRC.

although, all this was long ago, and my memory is faded.

32-bit Windows mostly stabilized the calling convention and
object-file format mess (nearly everything is either cdecl or
stdcall, and uses COFF...).

<--
Windows defines an ABI for C, I think (which it uses when
calling into system DLL's).
-->

well, or it can be said that there are 2 in common use:
stdcall (used for many DLL's) and cdecl (used for pretty much everything
else).

supporting both, one can interface with pretty much anything of relevance.

on many other systems, it is a single convention in use, but which it is
will vary from system to system (and the specifics will depend on the CPU
arch, ...).

but, Windows and x86 (or Windows and x64 / x86-64) represent the vast
majority of total systems (desktop and laptop at least) in use...
Linux and OSX (on x86 or x86-64) are most of the rest.

ARM and PPC are used in many embedded systems.
(not sure the OS popularity distribution for embedded systems, from what I
have seen I would guess: Linux, FreeDOS, and various proprietary OS's...).

most other architectures and operating systems can be largely safely
ignored...



in my case, I am still using the C calling conventions (for the specific
targets I support, mostly Windows and Linux), even for non-C languages (my
partial Java and C# implementation, as well as BGBScript, which is based on
ECMAScript).

granted, I do tend to use a modified ABI (I see the calling convention and
ABI as separate-but related, where an ABI may specify things not part of the
calling convention proper, and the calling convention is mostly responsible
for how data gets to/from the function on a given arch, but ignores
secondary issues such as function naming or sideband data).

yes, closures and similar are a bit of a hack (they use heap-allocated
"executable objects"), and there is no "good" way to handle full
continuations, so I largely ignore the latter (partial continuations can be
handled via a longjmp-like mechanism).

C level interop is possible then, but direct C++ level interop is not.
plugging between C++ and BGBScript would still require using 'extern "C" ',
and does not directly facilitate high-level types.
however, some level of interop is facilitated by dynamic code-generation
(mostly to try to patch together the BGBScript and C typesystems, where one
supports dynamic typing, and the other is primarily statically-typed...).

note: apart from some amount of either link-time or run-time generated code,
my ABI wouldn't work...
the ABI was largely originally designed to deal with dynamically-generated
code (though some information is redundant, as I originally designed it
before moving to using a database-like structure for code patching, so the
ABI had to be largely self-defining, rather than being able to rely on
external metadata queries to resolve many issues).

I had considered some possibility of using other (more specialized) calling
conventions, but decided against this due to the overall costs (for example,
a calling convention capable of pulling off full continuations would
necessarily have problems with C-level interop, and I know of know good way
to support full continuations in C apart from ugly stack-jumping hackery,
which is preferably avoided...).

static linking of C or C++ against BGBScript (or later C# or Java) also
currently doesn't work, as there is no real "good" way to handle late
binding in statically-compiled code (this means it is needed to fetch and
call through function pointers...).

dynamically-compiled C doesn't have this issue though (but has its own share
of issues, mostly the plague of compiler bugs...).


and so on...
 
G

Goran Pusic

That used to be true in the distant past, but not today.

I am sorry, but no. Additional argument to the way I see things: under
e.g. Windows, there's a myriad of OS interfaces that are exposed
through COM (e.g. Telephony API, to name but one example). Nobody in
their right mind is using these interfaces from C, but rather C++.

IOW, in theory, C language is incidental to OS interfaces. In
practice, much less so. :)

Goran.
 
B

BGB / cr88192

That used to be true in the distant past, but not today.

<--
I am sorry, but no. Additional argument to the way I see things: under
e.g. Windows, there's a myriad of OS interfaces that are exposed
through COM (e.g. Telephony API, to name but one example). Nobody in
their right mind is using these interfaces from C, but rather C++.

IOW, in theory, C language is incidental to OS interfaces. In
practice, much less so. :)
-->

is there any "particular" reason why people should not use COM interfaces
from C?...

one can argue, maybe it doesn't "mesh" with C's "normal way of doing things"
/ aesthetics, but this does not itself limit its usability (hell, maybe it
can just be claimed that using COM interfaces makes C look a little more
like C++?...).

and, if people *really* don't like the aesthetics, they can always just wrap
the thing.


in fact, there are several (mostly/purely) C codebases I know of that
internally use systems fairly similar to COM anyways, since it works well
for loosely coupled components (direct linking tends to cause problems in
certain cases, such as having a component which may or may not exist, ...,
so a COM-like system may be an improvement over some other strategies).

so then, what is the *real* basis for this claim?...

this sounds like personal bias, rather than an objective statement, FWIW...


or such...
 
A

Alf P. Steinbach /Usenet

* BGB / cr88192, on 27.08.2010 20:54:
<--
I am sorry, but no. Additional argument to the way I see things: under
e.g. Windows, there's a myriad of OS interfaces that are exposed
through COM (e.g. Telephony API, to name but one example). Nobody in
their right mind is using these interfaces from C, but rather C++.

IOW, in theory, C language is incidental to OS interfaces. In
practice, much less so. :)
-->

is there any "particular" reason why people should not use COM interfaces
from C?...

No, but then "should" makes the question pretty meaningless, and "particular"
put in quotes completes the removal of meaning from the question.

It's like asking if there's any "particular" reason why people shouldn't use
assembly language.

COM was designed for C++ and is hard enough in C++. In C it's a nightmare. You
have to emulate all that the C++ compiler does for you, e.g transforming call
p->foo( x ) into p->vtable->foo( p, x ), perhaps with a cast, and so on.

one can argue, maybe it doesn't "mesh" with C's "normal way of doing things"
/ aesthetics, but this does not itself limit its usability (hell, maybe it
can just be claimed that using COM interfaces makes C look a little more
like C++?...).

No, it just makes it look like gibberish.

and, if people *really* don't like the aesthetics, they can always just wrap
the thing.


in fact, there are several (mostly/purely) C codebases I know of that
internally use systems fairly similar to COM anyways, since it works well
for loosely coupled components (direct linking tends to cause problems in
certain cases, such as having a component which may or may not exist, ...,
so a COM-like system may be an improvement over some other strategies).

Yes, that is correct. Mozilla uses a COM-based scheme, and so does a common GUI
in Linux.

so then, what is the *real* basis for this claim?...

this sounds like personal bias, rather than an objective statement, FWIW...

No, but it's not a complete picture. Some parts of the Windows API are designed
for C++, true. Those parts are most naturally used from C++ or higher level
languages. But most of it is designed for C, and those parts are at least usable
from C (although also that's easier in C++). And some parts are designed for
scripting languages, and those parts are easy to use with scripting, pretty
horrible to use from C++ without special supportive libraries, and don't even
think about C. Although some folks at Microsoft did, and wrote books about it.

The binary interface, the ABI, is in all cases language agnostic.

But since the APIs are designed for different languages, different languages are
what you use. The common ABI just makes it a tad easier to combine languages.
Like writing a DLL in language A and use it from language B. This ABI is however
not an ABI supporting modern C++. There's no provision for multiple inheritance
or RTTI or C++ constructors/destructors; from a C++ point of view it's like
interfacing with code written in another language.


Cheers & hth.,

- Alf
 
Ö

Öö Tiib

Windows defines an ABI for C, I think (which it uses when
calling into system DLL's).

That ABI uses sort of Pascal way to call functions if i remember
correctly. Haven't looked long time into some ms header but i think
these are still that "stdcall".
 
B

BGB / cr88192

Alf P. Steinbach /Usenet said:
* BGB / cr88192, on 27.08.2010 20:54:

No, but then "should" makes the question pretty meaningless, and
"particular" put in quotes completes the removal of meaning from the
question.

It's like asking if there's any "particular" reason why people shouldn't
use assembly language.


ASM works as well, just due to verbosity and lacking portability, usually
makes it a worse choice except in cases when there is some reason an actual
HLL can't reasonably be used.

but, yes, I still use a fair amount of ASM as well... (most often, for
dynamically generating code in memory, where my assembler tends to be much
faster and more reliable than my C compiler, sadly enough making ASM a much
more attractive language for this task).

COM was designed for C++ and is hard enough in C++. In C it's a nightmare.
You have to emulate all that the C++ compiler does for you, e.g
transforming call p->foo( x ) into p->vtable->foo( p, x ), perhaps with a
cast, and so on.

I have often seen it as:
(*p)->foo(p, x);

but, either way...

No, it just makes it look like gibberish.

I have seen plenty worse...

but, in many cases, a lot of ones' code can end up half-way looking like
this anyways, especially when doing OOP-like stuff, ...

context and vtable structs are not exactly a rare thing, and function
pointers are nothing to be afraid of, ...

either way, one still ends up with a lot of "foo->bar".

Yes, that is correct. Mozilla uses a COM-based scheme, and so does a
common GUI in Linux.

yep.



No, but it's not a complete picture. Some parts of the Windows API are
designed for C++, true. Those parts are most naturally used from C++ or
higher level languages. But most of it is designed for C, and those parts
are at least usable from C (although also that's easier in C++). And some
parts are designed for scripting languages, and those parts are easy to
use with scripting, pretty horrible to use from C++ without special
supportive libraries, and don't even think about C. Although some folks at
Microsoft did, and wrote books about it.

The binary interface, the ABI, is in all cases language agnostic.

yes, fair enough.

in my case, I tend to also design my API's to be C friendly as well,
generally regarding C as "the least common denominator", and also it is the
implementation language of most of my other stuff as well.

also, many parts of my codebase are C-only, whereas others allow C++, as a
matter of policy.
technically, my policy also allows C# in some cases as well, but thus far I
don't use any C# in my main projects (thus far, it is an unreasonable
portability risk).

But since the APIs are designed for different languages, different
languages are what you use. The common ABI just makes it a tad easier to
combine languages. Like writing a DLL in language A and use it from
language B. This ABI is however not an ABI supporting modern C++. There's
no provision for multiple inheritance or RTTI or C++
constructors/destructors; from a C++ point of view it's like interfacing
with code written in another language.

fair enough.

some of my own API's implement dynamic typing and GC, although in some parts
of my codebase its use is a bit spotty (since I also like modularity, and
parts which directly depend on the GC or typesystem library, naturally
enough have a dependency on said libraries).

in some cases, I have gone and used (COM-like) interfaces, as these can
allow accessing a facility, but can more gracefully deal with the case where
it is absent.


this tends to involve though using OS facilities to get some of the core
components loaded, so that one can fetch some of the core interfaces, and
then use these to load additional components and gain access to their
interfaces as well.

then one may still be left writing code to "route" these interfaces to the
part of the codebase where they are actually needed (especially if getting
it to another library which is itself a dynamically loaded component).

this strategy can be convoluted (ugly initialization code doing a lot of
"plumbing"), and in many cases, it is easier just to be lazy and directly
link against the components.
 
J

James Kanze

I am sorry, but no. Additional argument to the way I see things: under
e.g. Windows, there's a myriad of OS interfaces that are exposed
through COM (e.g. Telephony API, to name but one example). Nobody in
their right mind is using these interfaces from C, but rather C++.

What does COM have to do with the OS?
IOW, in theory, C language is incidental to OS interfaces. In
practice, much less so. :)

In theory, we really have to start by defining what we mean by
"OS". I'm an old timer---for me, the OS is the part of the code
which has to be executed in kernel mode: things like COM or the
GUI aren't directly part of the OS. (But the border isn't
clear. Many years ago, all of the networking software was built
above the OS as well. Today, I don't know of a kernel that
doesn't have support for TCP/IP built in.) Given that, the
actual ABI must be in assembler, because C doesn't offer any
means of switching from user mode to kernel mode. However,
neither Windows nor any of the Unix I know publish this
interface; they make available a runtime library which provides
a C level interface to it. So from the user's point of view,
the ABI is defined in C.

Of course, addins like COM, the GUI, a data base... or the C++
standard library, may define the interface in any language they
want.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top