Topic: Linkage revisited


Author: imp@village.org (Warner Losh)
Date: 1995/08/14
Raw View
In article <4068ab$o58@senator-bedfellow.mit.edu>,
John Carr <jfc@mit.edu> wrote:
>Linkage is part of the type of a function (and therefore a function
>pointer type includes this information).  A "C" function can be called
>just like a C++ function except for overloading and possibly default
>arguments.

I have two objections to this.

First, how do I declare a type that is a pointer to an extern "C"
function that returns void and has no args?

extern "C" { typedef void (*fp)(); }

or

typdef extern "C" void (*fp)();

The second form gives me compiler errors.  I'm fairly sure that it
isn't allowed by the current grammar, the couple of quick compiler
tests show that no one accepts it.

The second is realted.  This would be the only type specifier that
applies only to functions, and its expression is non-orthogonal to the
rest of the language.  Since you can't easily declare these beasts, it
becomes much harder to use them.

The bottom line is that if you want to make it part of the type of a
function or a function pointer, much more work is needed on the draft
to reflect this fact.  I believe you will start running into some of
the same problems that member functions:
 Casting rules.  Can I cast a extern "C" to C++ and back again?
 Calling rules.  When it is defined and undefined to make calls
  through these pointers.
 Size issues.  Is an extern "C" pointer the same size as an
  extern "C++" pointer?

I think that someone needs to go through the working paper and tighten
up these issues, since the current draft isn't as clear as it could be
on this.

None of this is to say that this is an inherently bad idea, but many
hurdles still remain before these objects are first class C++ objects.

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/







Author: saroj@nynexst.com (Saroj Mahapatra)
Date: 1995/08/15
Raw View
I could not agree more with Fergus in this count.

- Saroj

[ The rest of the article is quoted material.
I decided to err in favour of inclusion, since after all
it was me that Saroj was quoting ;-)  -moderator (fjh). ]

In article 7618@mulga.cs.mu.OZ.AU, fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
> ark@research.att.com (Andrew Koenig) writes:
>
> >fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
> >
> >> [...] requiring C++ compilers to use the same calling convention as the
> >> underlying C compiler is still an option that is very much open to
> >> the committee.
> >
> >The committee has discussed this issue on and off for years,
> >and no one has yet proposed a satisfactory solution.
> >
> >Here are a few questions that should help point out why this is a
> >hard problem:
> >
> > 1. Suppose you have two mutually incompatible C compilers on
> > your machine?  Is every C++ compiler required to be compatible
> > with both of them?
>
> No, it clear that simply loading a new C compiler onto your hard disk
> should not suddenly make your C++ compiler non-conforming.
>
> > If not, suppose your C++ compiler is compatible
> > with only one of them and you remove that C compiler.  Does that
> > invalidate the C++ compiler?
>
> Suppose your hard disk crashes.  Does that invalidate the C++ compiler?
>
> (I think I've got the hang of a questions arms-race now ;-)
>
> Let me answer my question first, and then yours.  If I have Foobar C++
> on my hard disk, and it crashes, that does not mean that Foobar C++ is
> not a conforming C++ implementation.  To be pedantic, talking about
> whether or not Foobar C++ is a conforming implementation is a
> convenient simplification which breaks down in this situation.  Really
> we ought to only talk about the conformance of a particular computer
> system ("processor", to use the draft standard's terminology) --
> comprising of not just software, but also hardware and documentation.
> If my hard disk crashes, then the computer system sitting on my desk is
> not conforming, but of course Foobar C++ may still be part of some
> other conforming computer system whose hard drive has not crashed, and
> Foobar Inc. are certainly still justified in claiming that their
> product conforms to the standard.
>
> Now, suppose the C++ standard were to require that C++ implementations
> support interfacing to C.  Pedantically, you still can't talk about
> whether Foobar C++ is conforming; you have to talk about the
> conformance of a whole computer system.  If the C++ standard were to
> require implementations to support interfacing to C, then said computer
> system must clearly include a C compiler (or interpreter, etc.).
> Foobar C++ can still certainly claim conformance to the standard, even
> if it does not come packaged with a C compiler.  After all, it doesn't
> come packaged with a machine to run it on either!  Instead, there is
> usually a little note on the box - "requires an IBM compatible with a
> 386 or better and at least 8M of RAM and 100M of disk space, running
> Microsoft Windows" or something similar.  If Foobar C++ also requires
> Quux C to support the requirements in the C++ standard about
> interfacing to C, then they should document that too - but they can
> certainly still claim conformance to the standard.
>
> As before, if I remove the C compiler from my hard drive, or if my hard
> drive crashes, or if the power supply suddenly dies with a loud bang
> and a big cloud of black smoke (this has happened to me! ;-), then the
> computer system on my desk no longer comprises a "conforming
> processor", according to the definition in the C++ standard.  But that
> doesn't affect the right of Foobar Inc. to claim conformance with the
> C++ standard.
>
> > 2. Suppose the C compiler vendor changes linkage conventions
> > incompatibly.  Does that invalidate the C++ compiler?
>
> Supposing the OS vendor changes linkage conventions incompatibly [*].
> Does that invalidate the C++ compiler?
>
>  [*] This is not just hypothetical.  SGI changed the linkage
>  conventions incompatibly between Irix 4.x and 5.0.  When our
>  site upgraded, it broke the compiler (for Mercury, not C++)
>  that I and my colleagues have been writing.  Fixing it was
>  a decidedly non-trivial undertaking.
>
> The answer to these questions is the same as before.
> The Foobar C++ documentation should state which version(s) of the
> the Quux C compiler and which version(s) of the linker, program loader,
> extended/expanded/ex-whatever memory manager, shell, and OS (and
> any other software with which it must interact) it supports.
> Obviously if you change any of the software in the computer system,
> it may cause the resulting system to fail to be compliant.
> But that is not Foobar Inc.'s fault.
>
> >In both these cases, the question `Does that invalidate the C++ compiler'
> >means `Does the vendor of this C++ compiler lose the right to claim that
> >that compiler conforms to the standard?'
> >
> >If the answer is `yes,' that means that in effect one can produce a
> >standard-conforming C++ compiler only by permission of the C compiler
> >vendors for that machine.
>
> I don't agree.  Even if a standard-conforming C++ "processor" must
> include a C compiler, that does not implies that the vendor of a
> stand-alone C++ compiler cannot claim conformance with the standard.
> Clearly a C++ compiler does not on its own constitute a
> standard-conforming C++ "processor".  For that, you need at the very
> least an OS and a machine to run it on.  I don't think it would be
> unreasonable for the standard to require such a processor to also
> include a C compiler.
>
> >If the answer is `no,' it is hard to see how
> >to write a requirement for compatibility.
>
> The way it is done in the Ada 95 standard seems satisfactory to me -
> perhaps not ideal, but certainly much better than throwing up our hands in
> defeat in the belief that such a requirement cannot be phrased.
>
> --
> Fergus Henderson              | Designing grand concepts is fun;
> fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
> http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
> PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/15
Raw View
clamage@Eng.Sun.COM (Steve Clamage) writes:

>Now things get stickier. It's fine for you to say "name encoding scheme"
>and "calling conventions". But the standard would have to define what
>that means.
[...]
>We cannot solve all problems with a language standard.

Agreed, specifying ABIs and "name encoding schemes" is far beyond the
scope of the C++ standard.  But defining the behaviour of the following
C++ program certainly is.

void foo(void (*func)()) { (*func)(); }
void bar() {}
extern "C" void baz() {}

int main() {
foo(bar);
foo(baz);
return 0;
}

Should it be the same as `int main() { return 0; }', or should
it have undefined behaviour?  That is the unresolved issue.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/16
Raw View
[apologies if anyone sees this twice - fjh.]

clamage@Eng.Sun.COM (Steve Clamage) writes:

>Now things get stickier. It's fine for you to say "name encoding scheme"
>and "calling conventions". But the standard would have to define what
>that means.
[...]
>We cannot solve all problems with a language standard.

Agreed, specifying ABIs and "name encoding schemes" is far beyond the
scope of the C++ standard.  But defining the behaviour of the following
C++ program certainly is.

void foo(void (*func)()) { (*func)(); }
void bar() {}
extern "C" void baz() {}

int main() {
foo(bar);
foo(baz);
return 0;
}

Should it be the same as `int main() { return 0; }', or should
it have undefined behaviour?  That is the unresolved issue.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@cs.mu.oz.au (Fergus Henderson)
Date: 1995/08/16
Raw View
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:

>wil@ittpub.nl (Wil Evers) writes:
>
>> I know it's late, but with hindsight, allowing a C++ compiler to use
>> different calling conventions from the underlying C compiler was probably
>> a mistake.
>
>I don't think there's any choice about that decision:

I respectfully disagree.

>there's no
>guarantee that any particular C++ implementation has an underlying C
>compiler at all. In fact, most C++ implementations that I'm aware of
>compile C++ directly to machine code without ever passing though C.

There's no guarantee that the C implementation has an _underlying_ C
compiler, but the ARM [7.4] and the draft working paper [7.5] do state that

"Linkage to a function written in the C programming language ...
must be provided by every implementation".

While others have interpreted that differently, to me it seems pretty
clear, and existing practice seems to back it up 100%.

>It's likely that most programmers out there have one or more C
>compilers on their machines, but what good is that from the point of
>view of the C++ standard?  How could we conceivably word a requirement
>about interoperability between a C++ implementation and some other
>random C implementation?

There are several ways.

1.  Require each conforming C++ implementation to include a
conforming C implementation, and support interfacing between
the two.

This option would be not be too hard to state in the standard.
Whether or not it is a good idea is another question -
some parties might find this requirement too onerous.

2.  Define in the standard a notion of a "conforming combined C/C++
implementation", comprising of a conforming C implementation
and a conforming C++ implementation with an implementation-defined
mechanism for linking programs comprising translation units
written in C with translation units written in C++.
"Conforming C++ implementations" would not be required to support
interfacing to C, but "Conforming combined C/C++ implementations"
would.

This option would also not be too hard to state in the standard.
(The first sentence of the above paragraph would be nearly enough,
IMHO.)

3.  Don't bother to specify interoperability of C and C++.
Just specify that C++ programs can define functions with
extern "C" linkage, and specify that the addresses of
functions with extern "C" linkage and extern "C++" linkage
can be freely intermingled.  This side-steps the question,
but nevertheless gives an answer.

>That's totally outside the scope of a language standard.

No, it is not.  The Ada 95 standard defines requirements for Ada
implementations to interface to C, FORTRAN, and COBOL.  These
requirements are defined in one of the optional "Special Needs"
Annexes, so Ada implementations are not required to support interfacing
to any or all of these languages, but the requirements *are*
normative.  A conforming Ada implementation that does not support a
Special Needs Annex or part thereof must identify programs that use
unsupported features, either at compile time or by raising an exception
at run-time.  A conforming Ada implementation that claims to fully
support Annex B must allow interfacing with C, FORTRAN, and COBOL and
must abide by the semantics specified in that Annex.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/08
Raw View
In article <3vlhsd$s3i@engnews2.Eng.Sun.COM>,
Steve Clamage <clamage@Eng.Sun.COM> wrote:
>
>Personally, I think this area is best left as a "quality of implementation"
>issue. Any C++ implementor must make a reasonable effort to ensure
>compatibility with at least one common C compiler on the platform, or no one
>will use the C++ compiler. Usually, the C++ supplier supplies the C
>compiler as well, making this a non-issue.

 In the DOS world at least, the issue is compatibility
of the "compiler" with ITSELF. For example Borland does NOT produce
a C++ compiler, it produces 500 of them. You can change compilers
using switches to control memory models, target OS, object layout, mangled
name generation etc etc. Come to think of it, 500 is only 9 switches,
so it is too conservative.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/08
Raw View
In article <DCn5qw.94G@research.att.com>,
Andrew Koenig <ark@research.att.com> wrote:
>In article <1995Aug1.105954.1403@ittpub> wil@ittpub.nl (Wil Evers) writes:
>
>> I can't understand why the committee is having such a hard time over this
>> issue. Why not just require a C++ implementation to specify with which C
>> compiler(s) (and versions) it is compatible on a given platform?
>
>Such a requirement is uninteresting, because
>a vendor can simply say `Our C++ implementation is not
>compatible with any C compilers' and meet the requirement
>that way.

 But that is fine! The interesting thing about the requirement
is that a compatibility claim ought to be documented -- and one that
IS documented can be checked by conformance testers.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/08/09
Raw View
In article <406nqo$2ul@rover.village.org> imp@village.org (Warner Losh)
writes:
> In article <4068ab$o58@senator-bedfellow.mit.edu>,
> John Carr <jfc@mit.edu> wrote:
> >Linkage is part of the type of a function (and therefore a function
> >pointer type includes this information).  A "C" function can be called
> >just like a C++ function except for overloading and possibly default
> >arguments.
>
> I have two objections to this.
>
> First, how do I declare a type that is a pointer to an extern "C"
> function that returns void and has no args?
>
> extern "C" { typedef void (*fp)(); }
>
> or
>
> typdef extern "C" void (*fp)();
>
> The second form gives me compiler errors.  I'm fairly sure that it
> isn't allowed by the current grammar, the couple of quick compiler
> tests show that no one accepts it.
>
> The second is realted.  This would be the only type specifier that
> applies only to functions, and its expression is non-orthogonal to the
> rest of the language.  Since you can't easily declare these beasts, it
> becomes much harder to use them.

[snip]

Please note that even if pointers to functions with extern "C" and extern
"C++" linkage could safely be assigned to each other, the syntactic
problems you mention remain. Requiring a C++ compiler to use the same
calling conventions for both extern "C" and extern "C++" seems technically
feasible, although it may be difficult to express this in standardese.

But what if a compiler vendor decides to add support for extern "Pascal"
to provide linkage to a large collection of routines written in that
language? If this is to have any real use, it seems highly unlikely the
calling conventions for extern "C++" and extern "Pascal" can be the same.
Therefore, I think C++ should provide a mechanism to express pointers to
functions with foreign linkage.

- Wil





Author: jfc@mit.edu (John Carr)
Date: 1995/08/09
Raw View
In article <406nqo$2ul@rover.village.org>, Warner Losh <imp@village.org> wrote:

I proposed for linkage:
>>Linkage is part of the type of a function (and therefore a function
>>pointer type includes this information).  A "C" function can be called
>>just like a C++ function except for overloading and possibly default
>>arguments.

>First, how do I declare a type that is a pointer to an extern "C"
>function that returns void and has no args?
>
>extern "C" { typedef void (*fp)(); }
>or
>typdef extern "C" void (*fp)();

>The second is realted.  This would be the only type specifier that
>applies only to functions, and its expression is non-orthogonal to the
>rest of the language.

This is a minor annoyance.  I think accepting it is worth than fixing
it (making `extern "<lang spec>"' a modifier like const or volatile
would make variables and non-function types a special case).  I would
like to see `extern "<lang spec>"' changed slightly so any declaration
can follow it, including static or typedef.  Ideally the spelling would
be changed not to include "extern" but it is probably too late for that.


>The bottom line is that if you want to make it part of the type of a
>function or a function pointer, much more work is needed on the draft
>to reflect this fact.  I believe you will start running into some of
>the same problems that member functions:
> Casting rules.  Can I cast a extern "C" to C++ and back again?
> Calling rules.  When it is defined and undefined to make calls
>  through these pointers.
> Size issues.  Is an extern "C" pointer the same size as an
>  extern "C++" pointer?

The existing answers for different type functions still work.  I'm assuming
C++ inherits the C rule: a function pointer can be converted freely to other
function pointer types, but a call to a function using a pointer to a function
of a different type has undefined results.  This means either the function
pointers must be the same size or the implementation must be prepared to
accept loss of information (one could imagine an implementation where C++
function pointers encoded the type of the function for run time checking;
as long as the implementation defined a "don't check" type conversions between
C and C++ function pointers would still work).

--
    John Carr (jfc@mit.edu)





Author: imp@village.org (Warner Losh)
Date: 1995/08/09
Raw View
In article <1995Aug9.101606.1434@ittpub>, Wil Evers <wil@ittpub.nl> wrote:
>Please note that even if pointers to functions with extern "C" and extern
>"C++" linkage could safely be assigned to each other, the syntactic
>problems you mention remain. Requiring a C++ compiler to use the same
>calling conventions for both extern "C" and extern "C++" seems technically
>feasible, although it may be difficult to express this in standardese.

I think that we're agreeing here.

If the standard says that extern "C" and extern "C++" function
pointers can't be freely intermixed, then the standard should provide
an easy and convenient way for me to express what type of linkage the
function has so that the compiler can check these silly things for me.
Also, I want to be able to write code that I don't have to resort to
the hack of

extern "C" void foo( int, int );

void foo( int a, int b)
{
 ...
}

or even sillier hackes when it comes to the typedef examples that I
gave earlier.

extern "C" right now is fundamentally different than anything else in
the C++ type model.  const, volitile, et al can appear anywhere they
are for that type.  However, extern "C" can appear only in a very
limited number of contexts that limits its use and makes it harder to
write a type safe program.

I do understand that if extern "C" works or not is a different issue.
The language must say that if external linkage "X" works, and the
linkage is part of the type, then this call is safe or that call is
not safe.  If external linkage "X" doesn't work, then a compiler
diagnostic should be required.

I think the other issues raised can be delt with easily, but it will
take time to work out this dark corner of the language and I fear it
may be too late for the standards process.

Warner

--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/07
Raw View
Warner Losh (imp@village.org) wrote:
|> In article <3vo9lr$los@metro.ucc.su.oz.au>,
|> John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
|> > It isn't clear it is POSSIBLE to use qsort.
|> >Suppose extern "C" functions use a DIFFERENT calling convention.

|> This sounds like another of the committee's unwise calls.  I do
|> understand the issues behind it, however, there is some legacy code
|> that depends on being able to call qsort from C++.

|> > Result: qsort may not be useable: it has to be there,
|> >it doesn't have to be useful. You certainly can't assume at this
|> >point in time any use of it will be portable. The final Standard
|> >might provide better guarrantees, but I have doubts.

|> This is the part that worries me the most.  Traditionally, you've been
|> able to do this, and as far as I know it works on all existing
|> compilers (at least the major ones I've used).  Breaking this now
|> isn't the best possible service that the committee could do to the
|> application developers (although it does let the compiler writers off
|> the hook more easily).

It wasn't supported by the Zortech compilers under MS-DOS.  C and C++
used different linkage conventions.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428)
Date: 1995/08/07
Raw View
In article <3vo9lr$los@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
-->In article <KANZE.95Jul25103036@slsvhdt.lts.sel.alcatel.de>,
-->James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
-->
-->>May I ask a question: why all these worries about qsort?  Why not just
-->>use sort (section 25.3.1.1)?  It is more flexible, and the benchmarks
-->>I've see suggest it is (as is to be expected) faster.

The point is: why are people only interested in qsort?  There are a million
and one third-party C libraries that I want to use plus quite a few
Fortran ones.

--> It isn't clear it is POSSIBLE to use qsort.
-->Suppose extern "C" functions use a DIFFERENT calling convention.

So?  When I say a function is ``extern "C"'' I expect the compiler
to do what it takes to call that function.  If C functions use a
different calling convention to C++ functions I would expect the
compiler to deal with that just as it deals with different name-mangling
conventions.  A compiler that didn't would be pretty stupid!

Of course the problem with qsort is that it isn't possible to define
the calling convention of a pointer to a function.  This is a language
defect that ought to be rectified!  In fact, I was quite surprised
to find out that this wasn't the case.  A) It seemed such an obvious
requirement that I never imagined it wouldn't be supported.
B) I'm sure I have written

extern "C"
    {
    typedef int (*CFunction) (int);
    };

and had it compile successfully.

--> Question 1: what is the calling convention of a function passed
-->to such a function -- C or C++? Answer: C because otherwise qsort
-->would not work.

Answer: it should depend on how the parameter is declared!

--> Question 2: can you compile an extern "C" function in C++?
-->Answer: not necessarily.

Answer: you should be able to.

...and I have written `` extern "C" { static int F (int i) { ...} }; ''!

--> Question 3: can you call code compiled with a C compiler?
-->Answer: not necessarily.

Answer: you should be able to.  (Though obviously the C compilers supported
will depend on the C++ compiler being used.)

It's a pragmatic issue.  I want/need to be able to use libraries
written in a language other than C++.  I don't see that this
is asking too much.  (However, I can see that the Committee might
have a hard job translating such pragmatic considerations into
standardese.)

As has been pointed out, ``extern "C"'' is a bit misleading in that it kind
of implies (and people often infer) that it means "implemented in the language C"
but it means "that follows the link-time/run-time function call convention
called `C'".  Those of us who have worked on the different Microsnot systems
with their various Pascal, syscall, fastcall, ... calling conventions are used
to the idea that a calling convention has nothing to do with the language of
implementation as almost none of the extern __pascal functions we called were
ever written in Pascal and there is no language called "syscall".

Thus, it is not always possible to give a unique definition ``extern "C"''
for any given platform.  (One might need several ``extern "C"''s, but that's not
a problem: one could easily have ``extern "C/Borland"'' and ``extern "C/Microsoft"''
as required.)  It's a compiler-dependent issue.  However, pragmatically speaking,
there's not really a problem as there is a generally accepted convention on
most platforms.

-- jP --







Author: pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428)
Date: 1995/08/07
Raw View
In article <1995Aug4.163853.11570@forte.com>, mikes@forte.com (Mike Schilling) writes:
-->I'd like the Standard to say something like "A C++ compiler must define
-->which C compilers it supports extern "C" access to.  extern "C" access to
-->is defined precisely as: ..."

Well, it's not actually possible to give a complete list of all the compilers
extern "C" is compatible with as the contents of that list vary and are outside the
control of the C++ compiler vendor.  Defining what the "C" convention means is is
rather more useful.

-->It is still useful for the Standard to define how
-->extern "C" behaves, so that programs using it can be portable among
-->compilers which support it.

It's not possible for the standard to define how ``extern "C"'' behaves
because there is no single C calling convention -- even on a given
hardware platform there could be many.  Until there is some globally
defined set of calling conventions names it won't be possible
to say what ``extern "anything"''

However, pragmatically there *is* an ``obvious'' meaning for ``extern "C"''
in many cases (e.g. as defined by that same vendors C compiler) so it's
probably worth keeping it, even if it's not well-defined.  I just
don't envy the Standard Committee's job trying to find the wording to
express what ``extern "C"'' means.

-- jP --







Author: jimad@microsoft.com (James L Adcock)
Date: 1995/08/07
Raw View
In article <3vsaaj$1gs@rover.village.org>, imp@village.org says...
>
>In article <3vo9lr$los@metro.ucc.su.oz.au>,
>John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
>>       It isn't clear it is POSSIBLE to use qsort.
>>Suppose extern "C" functions use a DIFFERENT calling convention.
>
>This sounds like another of the committee's unwise calls.  I do
>understand the issues behind it, however, there is some legacy code
>that depends on being able to call qsort from C++.
>
>>       Result: qsort may not be useable: it has to be there,
>>it doesn't have to be useful. You certainly can't assume at this
>>point in time any use of it will be portable. The final Standard
>>might provide better guarrantees, but I have doubts.
>
>This is the part that worries me the most.  Traditionally, you've been
>able to do this, and as far as I know it works on all existing
>compilers (at least the major ones I've used).  Breaking this now
>isn't the best possible service that the committee could do to the
>application developers (although it does let the compiler writers off
>the hook more easily).
>
>IMHO, if qsort is part of the language, then it must be possible to
>write extern "C" functions in C++ and have the compiler cope.  After
>all, it *KNOWS* that the function is extern "C", so it should know
>enough to have it follow the 'C' ABI should it differ from the C++
>ABI.
>
>This isn't the more subtle issue of what that ABI actually is, merely
>a requirement that C++ functions that have "C" linkage must follow
>whatever ABI that the compiler uses for those functions.  Right now
>the compiler must be able to correctly call these functions (if it
>supports a "C" ABI).  It would seem prudent to require that the
>compiler generate callable functions as well as calls to functions.
>
>Or have I missed something subtle in this thread?
>
>Warner
>--
>Warner Losh             "VMS Forever"           home: imp@village.org
>Cyberspace Development, Inc                     work: imp@marketplace.com
>Makers of TIA, The Internet Adapter.            http://marketplace.com/

--
The opinions expressed in this message are my own personal views
and do not reflect the official views of Microsoft Corporation.

In practice existing "C" linkage is defined by the host or target system,
not by a particular compiler.  Otherwise a given compiler is going
to have an awfully hard time calling any system libraries.
Thus "C" linkage rules are neither up to
the C++ committee nor any C committee to decide.

If/when "OO" operating systems catch on, then "C++" linkage
issues [better know as the "object model" for that particular OS]
may in turn be effectively defined by these "OO" operating
systems.  Any compiler not supporting the standard operating
system "OO" linkages, or making them a pain to use, would
be unpopular, to put it mildly.

These are not new issues, but rather have been rediscovered
many times in the past as new operating systems have come
out and caught on.  The compilers not adapting to the needs
of the operating system and programmers using those operating
systems fall behind.

Part of the trick of standardizing a language is realizing
what isn't yours to standardize.  C was successfully standardized
by leaving OS-dependent issues out of the standard.








Author: jfc@mit.edu (John Carr)
Date: 1995/08/07
Raw View
In article <DCyD2M.46H@tigadmin.ml.com>,
Julian Pardoe LADS LDN X1428 <pardoej@lonnds.ml.com> wrote:

>However, pragmatically there *is* an ``obvious'' meaning for ``extern "C"''
>in many cases (e.g. as defined by that same vendors C compiler) so it's
>probably worth keeping it, even if it's not well-defined.  I just
>don't envy the Standard Committee's job trying to find the wording to
>express what ``extern "C"'' means.

I think it can be done easily:

Linkage is part of the type of a function (and therefore a function
pointer type includes this information).  A "C" function can be called
just like a C++ function except for overloading and possibly default
arguments.

A function type defined within the scope of an extern "C" declaration
is a "C" function.

Everything else comes out of existing rules:

If the "C" function is not defined in a C++ source file the behavior is
implicitly undefined (it's not a C++ function so the standard can't say
what happens).

A "C" function obeys C++ syntax rules, not C.

If a "C" function is called by a pointer to C++ function, the behavior
is explicitly undefined (this is calling through a pointer to a different
type of function, just like calling a function returning double using a
pointer to function returning int).  If a "C++" function is called using
a pointer to "C" function, the behavior is likewise undefined.

Note that I said nothing about the C language.  Quality of implementation
will encourage compilers to make "C" functions use a calling convention
compatible with C compilers; the standard can not force them to do so except
by requiring all C++ compilers to have a C mode and incorporating the C
standard into the C++ standard.

The restriction that a compiler know the type of a function at the point
of the call should be sufficient for it to generate code with the correct
calling sequence.  It may be desirable to modify the argument checking
rules.  The C++ rules can work for C, but not for other languages in general.


--
    John Carr (jfc@mit.edu)





Author: imp@village.org (Warner Losh)
Date: 1995/08/07
Raw View
In article <4068ab$o58@senator-bedfellow.mit.edu>,
John Carr <jfc@mit.edu> wrote:
>Linkage is part of the type of a function (and therefore a function
>pointer type includes this information).  A "C" function can be called
>just like a C++ function except for overloading and possibly default
>arguments.

I have two objections to this.

First, how do I declare a type that is a pointer to an extern "C"
function that returns void and has no args?

extern "C" { typedef void (*fp)(); }

or

typdef extern "C" void (*fp)();

The second form gives me compiler errors.  I'm fairly sure that it
isn't allowed by the current grammar, the couple of quick compiler
tests show that no one accepts it.

The second is realted.  This would be the only type specifier that
applies only to functions, and its expression is non-orthogonal to the
rest of the language.  Since you can't easily declare these beasts, it
becomes much harder to use them.

The bottom line is that if you want to make it part of the type of a
function or a function pointer, much more work is needed on the draft
to reflect this fact.  I believe you will start running into some of
the same problems that member functions:
 Casting rules.  Can I cast a extern "C" to C++ and back again?
 Calling rules.  When it is defined and undefined to make calls
  through these pointers.
 Size issues.  Is an extern "C" pointer the same size as an
  extern "C++" pointer?

I think that someone needs to go through the working paper and tighten
up these issues, since the current draft isn't as clear as it could be
on this.

None of this is to say that this is an inherently bad idea, but many
hurdles still remain before these objects are first class C++ objects.

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/08
Raw View
In article <3vsaaj$1gs@rover.village.org>, Warner Losh <imp@village.org> wrote:
>In article <3vo9lr$los@metro.ucc.su.oz.au>,
>John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
>> It isn't clear it is POSSIBLE to use qsort.
>
>> Result: qsort may not be useable: it has to be there,
>>it doesn't have to be useful. You certainly can't assume at this
>>point in time any use of it will be portable. The final Standard
>>might provide better guarrantees, but I have doubts.

[]

>This isn't the more subtle issue of what that ABI actually is, merely
>a requirement that C++ functions that have "C" linkage must follow
>whatever ABI that the compiler uses for those functions.  Right now
>the compiler must be able to correctly call these functions (if it
>supports a "C" ABI).  It would seem prudent to require that the
>compiler generate callable functions as well as calls to functions.
>
>Or have I missed something subtle in this thread?

 I don't think so, and probably the CD requires exactly what
you have said -- at present. However the issue is being examined.
Many subtlties can arise in this area. (****)

 In practice, you only call "C" functions when you have to
for some reason and you are going to have to rely on your
implementor there and not the Standard _anyhow_.

 The only functions in the scope of the Standard seriously
affected are qsort, bsearch, et al from the C Standard library
-- which there is no reason to use anyhow in portable C++,
since STL provides a superior method of doing the same job.

[****] It isn't clear if you take a hunk of code and wrap it
in "extern "C" { ... }" exactly which bits will be C compliant
and which bits will be C++ compliant. For example the rules
in C and C++ for enum's differ: C enums are ints, C++ enums
can have a different size. This is just off the top of
my head -- there would be a very large range of difficult questions
here and "implementation defined" is the safest course for the
Standard. Any stronger guarrantee might be nice if consenus is
reached that such can be workable.

The point is there is no reason to use extern "C" in
portable programs.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/08/04
Raw View
IMHO the standard should say something like:
1. 'extern "XXX"' linkage _allows_ the compiler to use create code differently
   to 'extern "YYY"' linkage.
2. For names with external linkage that is not 'extern "C++"' there _may_ be
   restrictions compared to 'extern "C++"'.
3. Any C++ compiler shall support at least 'extern "C++"' and 'extern "C"'.
4. If not noted otherwise this standard describes only the behavior of
   'extern "C++"' linkage.
5. If a name from the Standard C Library is not 'extern 'C++"' then it
   _shall_ be 'extern "C++"' (see 17.3.2.2,2). 'extern "C"' linkage _should_
   allow _further_ compatibility to C implementations.

IMO this gives us what we want and what we can get:
ad 1. A compiler which allows 'extern "Fortran"' is still a legal C++ compiler.
ad 2. It is _legal_ (but not necessary and not in the scope of the standard)
      to have a restriction like
      - functions with extern "C" linkage can not be overloaded
      - functiontypes with extern "Pascal" linkage are not compatible to
        functiontypes with extern "C" or "C++" linkage.
ad 5. As we've seen in the discussion before, it is not sensible to require
      compatibility to a specific C implementation. It not even makes sense
      to make it implementation defined to which it is compatible, as there
      might be no C implemenation at all or it could just name C implementations
      that are not available (yet / any more).


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Fakult   t f   r Informatik, Technische Universit   t M   nchen, Germany.
email: schuenem@informatik.tu-muenchen.de
WWW:   http://www.informatik.tu-muenchen.de/cgi-bin/nph-gateway/hphalle2/~schuenem/index.html
...there is only one way to "skin a C+@"...:)  -- Jim Fleming






Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/04
Raw View
In article hmu@sunsystem5.informatik.tu-muenchen.de, schuenem@informatik.tu-muenchen.de (Ulf Schuenemann) writes:
>
>IMHO the standard should say something like:
>1. 'extern "XXX"' linkage _allows_ the compiler to use create code differently
>   to 'extern "YYY"' linkage.
>2. For names with external linkage that is not 'extern "C++"' there _may_ be
>   restrictions compared to 'extern "C++"'.
>3. Any C++ compiler shall support at least 'extern "C++"' and 'extern "C"'.
>4. If not noted otherwise this standard describes only the behavior of
>   'extern "C++"' linkage.

I believe the above points are already covered by the standard.

>5. If a name from the Standard C Library is not 'extern 'C++"' then it
>   _shall_ be 'extern "C++"' (see 17.3.2.2,2). 'extern "C"' linkage _should_
>   allow _further_ compatibility to C implementations.

I wonder if you have a typo in the first sentence of #5; I don't understand it.
The second sentence is not appropriate in a normative part of the standard,
since it doesn't make a requirement that can be verified.

>
>IMO this gives us what we want and what we can get:
>ad 1. A compiler which allows 'extern "Fortran"' is still a legal C++ compiler.

That is already the case.

>ad 2. It is _legal_ (but not necessary and not in the scope of the standard)
>      to have a restriction like
>      - functions with extern "C" linkage can not be overloaded
>      - functiontypes with extern "Pascal" linkage are not compatible to
>        functiontypes with extern "C" or "C++" linkage.

That is already the case.

>ad 5. As we've seen in the discussion before, it is not sensible to require
>      compatibility to a specific C implementation. It not even makes sense
>      to make it implementation defined to which it is compatible, as there
>      might be no C implemenation at all or it could just name C implementations
>      that are not available (yet / any more).

Agreed, and that is why the standard says so little about 'extern "C"':
there isn't much that can be said.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/08/04
Raw View
In article <3vtin5$m5t@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:


> Agreed, and that is why the standard says so little about 'extern "C"':
> there isn't much that can be said.

One thing the standard might say, though, is that it's possible to
define (not just declare) a function that has extern "C" linkage.
Considering that there are standard library functions that require
functions with extern "C" linkage, it would be nice if there were
some guarantee that those standard library functions were usable.
--
  Matt Austern                             He showed his lower teeth.  "We
  matt@physics.berkeley.edu                all have flaws," he said, "and
  http://dogbert.lbl.gov/~matt             mine is being wicked."





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/04
Raw View
In article 95Aug4103842@godzilla.EECS.Berkeley.EDU, matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
>In article <3vtin5$m5t@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:
>
>> Agreed, and that is why the standard says so little about 'extern "C"':
>> there isn't much that can be said.
>
>One thing the standard might say, though, is that it's possible to
>define (not just declare) a function that has extern "C" linkage.

You can. You have always been able to do so.

 extern "C" int foo(int) { ... }

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/04
Raw View
In article 13300@mulga.cs.mu.OZ.AU, fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>>Anyway, enough quibbling.  Do I understand from this discussion that
>>
>>** (A) ** In ANSI C++ there will be no way to declare a pointer to a function
>>with non-C++ linkage.
>
>I for one would not like to predict the future.
>I think the only think one can say for certain is that
>the answer to your question is as yet uncertain.

At the July meeting of the C++ Committee, the question of linkage and function
pointers was put on the list of unresolved issues.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: mikes@forte.com (Mike Schilling)
Date: 1995/08/04
Raw View
Andrew Koenig (ark@research.att.com) wrote:
: In article <1995Aug3.110213.1412@ittpub> wil@ittpub.nl (Wil Evers) writes:
:
: > > Such a requirement is uninteresting, because
: > > a vendor can simply say `Our C++ implementation is not
: > > compatible with any C compilers' and meet the requirement
: > > that way.
:
: > Why would such a statement be uninteresting? If I was looking for a decent
: > C++ compiler, I'd be more than interested.
:
: But your interest would be the same whether the Standard
: said anything about it or not.  That's the point.

I'd like the Standard to say something like "A C++ compiler must define
which C compilers it supports extern "C" access to.  extern "C" access to
is defined precisely as: ..."

A C++ compiler could indeed say `Our C++ implementation does not support
extern "C" access to any compilers'; it would
be a poor if conforming implementation, only useful for people who never
use extern "C".  It is still useful for the Standard to define how
extern "C" behaves, so that programs using it can be portable among
compilers which support it.

Mike





Author: greghunt@zeta.org.au
Date: 1995/08/06
Raw View
It may be uninteresting to require a C++ compiler to simply state that it is compatible with
a specific C compiler, but is certainly clearer than: "there must exist an ANSI C compiler with
which object from a conforming C++ compiler can be linked".  What IS the committee trying
to achieve by defining this?  It appears that the committee is starting to venture into defining
underlying linkage mechanisms.  Personally I would prefer "clearly stated and boring" to
"implied (where IS this stated in the draft?) and having exciting/aggravating consequences".
A sensible implementor will will have to document the compatability in any case - just as they
have to today for other languages.

Can I link IBM Ad-Cycle C-370 with BAL?  Not using standard MVS linkage you can't, there are
additional registers that must be preserved across calls - the book tells me.  Can I link
IBM C-370 V1 with AD-Cycle C?  Not sure... - have to look in the book - and when there is a
C++ implementation on MVS - what does it link with?  Well, I'll have to go look in the book
for that too.  This is not a real bother and is no surprise.  Is the committee trying to save me
from the reading?







Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/01
Raw View
In article 1403@ittpub, wil@ittpub.nl (Wil Evers) writes:
>In article <DCErIA.IJt@research.att.com> ark@research.att.com (Andrew
>Koenig) writes:
>>
>> Here are a few questions that should help point out why this is a
>> hard problem:
>>
>>  1. Suppose you have two mutually incompatible C compilers on
>>  your machine?  Is every C++ compiler required to be compatible
>>  with both of them?  If not, suppose your C++ compiler is
>compatible
>>  with only one of them and you remove that C compiler.  Does that
>>  invalidate the C++ compiler?
>>
>>  2. Suppose the C compiler vendor changes linkage conventions
>>  incompatibly.  Does that invalidate the C++ compiler?
>>
>> In both these cases, the question `Does that invalidate the C++
>compiler'
>> means `Does the vendor of this C++ compiler lose the right to claim that
>> that compiler conforms to the standard?'
>>
>> If the answer is `yes,' that means that in effect one can produce a
>> standard-conforming C++ compiler only by permission of the C compiler
>> vendors for that machine.  If the answer is `no,' it is hard to see how
>> to write a requirement for compatibility.
>
>I can't understand why the committee is having such a hard time over this
>issue. Why not just require a C++ implementation to specify with which C
>compiler(s) (and versions) it is compatible on a given platform?

Let's suppose the committee makes exactly that requirement. Your C++
compiler manual says "This C++ compiler is compatible with the XYZ C
compiler, version 2.0.2," thus complying with the requirement. Are you now
better off than you were before?

I don't think so, unless you happen to use the XYZ C compiler, version 2.0.2.
If you use the TUV C compiler, you would have to find out about its compatibility
with XYZ or with your C++ compiler somehow. If you use XYZ version 1.9.8
or version 2.1, you have to do the same research.

What you really want is an ABI on the platform, and assurances that your
C++ compiler and your C compiler each follow the ABI. That is outside the
scope of the C++ standard.

Personally, I think this area is best left as a "quality of implementation"
issue. Any C++ implementor must make a reasonable effort to ensure
compatibility with at least one common C compiler on the platform, or no one
will use the C++ compiler. Usually, the C++ supplier supplies the C
compiler as well, making this a non-issue. Whether that is so or not, the
C++ vendor must, out of self-interest, tell you about compatibility with
other compilers on the system.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/08/01
Raw View
In article <3vlhsd$s3i@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:

> >I can't understand why the committee is having such a hard time over this
> >issue. Why not just require a C++ implementation to specify with which C
> >compiler(s) (and versions) it is compatible on a given platform?
>
> Let's suppose the committee makes exactly that requirement. Your C++
> compiler manual says "This C++ compiler is compatible with the XYZ C
> compiler, version 2.0.2," thus complying with the requirement. Are you now
> better off than you were before?

To expand on Steve's points: what happens if XYZ corporation stops
selling version 2.0.2 of its compiler?  Does that mean that your C++
compiler is no longer standard-conforming?  Or what happens if you
want to write a C++ compiler for a platform for which there isn't any
C compiler?  (That's not as artificial a what-if as you might think:
don't forget embedded systems.)

C and C++ are different languages.  I just don't see that cross-language
compatibility are within the scope of the C++ standard.

--
  Matt Austern                             He showed his lower teeth.  "We
  matt@physics.berkeley.edu                all have flaws," he said, "and
  http://dogbert.lbl.gov/~matt             mine is being wicked."





Author: ark@research.att.com (Andrew Koenig)
Date: 1995/08/01
Raw View
In article <1995Aug1.105954.1403@ittpub> wil@ittpub.nl (Wil Evers) writes:

> I can't understand why the committee is having such a hard time over this
> issue. Why not just require a C++ implementation to specify with which C
> compiler(s) (and versions) it is compatible on a given platform?

Such a requirement is uninteresting, because
a vendor can simply say `Our C++ implementation is not
compatible with any C compilers' and meet the requirement
that way.
--
    --Andrew Koenig
      ark@research.att.com





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/01
Raw View
>jason@cygnus.com (Jason Merrill) writes:
>--> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
>-->
>-->> This is a serious incompatibility with C, since it makes it impossible
>-->> to pass the address of a static function to qsort().
>-->
>-->No, it doesn't.
>-->
>-->extern "C" {
>-->  static int qsort_callback (const void *, const void *) { ... }
>-->}

I haven't seen Jason Merill's post yet, except as quoted above.
But the ARM and the draft working paper *clearly* state that the
linkage-specification in the above example has no effect.

|   7.5  Linkage specifications                                 [dcl.link]
|
| 5 Linkage can be specified for objects.  [Example:
|           extern "C" {
|               // ...
|               _iobuf _iob[_NFILE];
|               // ...
|               int _flsbuf(unsigned,_iobuf*);
|               // ...
|           }
|    --end example] Functions and objects can be declared static or inline
|   within  the  {}  of a linkage specification.  THE LINKAGE DIRECTIVE IS
|   IGNORED FOR A FUNCTION OR OBJECT WITH INTERNAL LINKAGE (_basic.link_).
|   A  function  first  declared  in  a linkage specification behaves as a
|   function with external linkage.  [Example:
|           extern "C" double f();
|           static double f();     // error
|   is ill-formed (_dcl.stc_).  ] An object defined within an
|           extern "C" { /* ... */ }
|   construct is still defined (and not just declared).

pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428) writes:

>Anyway, enough quibbling.  Do I understand from this discussion that
>
>** (A) ** In ANSI C++ there will be no way to declare a pointer to a function
>with non-C++ linkage.

I for one would not like to predict the future.
I think the only think one can say for certain is that
the answer to your question is as yet uncertain.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/01
Raw View
huber@kazoo.cs.uiuc.edu (Jay Huber) writes:

>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
>
>>This is a serious incompatibility with C, since it makes it impossible
>>to pass the address of a static function to qsort().
>
>But giving a function extern "C" linkage does not give the function
>external linkage.  For example,
>
>extern "C" void f();
>
>static void f() { cout << "ok" << endl; }
>
>Here, f has extern "C" linkage, but is not external.  It cannot
>be referneced from another module.  Take out the 'static' and it can.
>
>The above example works with CodeWarrior 6, but I'm unable to tell
>by reading the ARM if the example is correct.

That's very creative, but your example is definitely not allowed
according to the draft standard.   (For what it's worth, your
example is also rejected by Cfront 2.0.)

Here's the relevant sections from the April working paper.
I've used uppercase to highlight the pertinent sentences.

|   7.5  Linkage specifications                                 [dcl.link]
|
| 5 Linkage can be specified for objects.  [Example:
|           extern "C" {
|               // ...
|               _iobuf _iob[_NFILE];
|               // ...
|               int _flsbuf(unsigned,_iobuf*);
|               // ...
|           }
|    --end example] Functions and objects can be declared static or inline
|   within  the  {}  of a linkage specification.  The linkage directive is
|   ignored for a function or object with internal linkage (_basic.link_).
|   A  FUNCTION  FIRST  DECLARED  IN  A LINKAGE SPECIFICATION BEHAVES AS A
|   FUNCTION WITH EXTERNAL LINKAGE.  [EXAMPLE:
|           extern "C" double f();
|           static double f();     // ERROR
|   IS ILL-FORMED (_dcl.stc_).  ]

The cross-reference to `dcl.stc' refers to the following text:

|   7.1.1  Storage class specifiers                              [dcl.stc]
|
| 7 THE  LINKAGES  IMPLIED  BY  SUCCESSIVE DECLARATIONS FOR A GIVEN ENTITY
|   SHALL AGREE.  That is, within a given scope, each declaration  declar
|   ing  the  same  object name or the same overloading of a function name
|   shall imply the same linkage.  Each function in a given set  of  over
|   loaded functions can have a different linkage, however.  [Example:
|           static char* f(); // f() has internal linkage
|           char* f()         // f() still has internal linkage
|               { /* ... */ }
|           char* g();        // g() has external linkage
|           static char* g()  // ERROR: INCONSISTENT LINKAGE
|               { /* ... */ }

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: jbuck@synopsys.com (Joe Buck)
Date: 1995/08/02
Raw View
In article <1995Aug1.105954.1403@ittpub> wil@ittpub.nl (Wil Evers) writes:
>> I can't understand why the committee is having such a hard time over this
>> issue. Why not just require a C++ implementation to specify with which C
>> compiler(s) (and versions) it is compatible on a given platform?

ark@research.att.com (Andrew Koenig) writes:
>Such a requirement is uninteresting, because
>a vendor can simply say `Our C++ implementation is not
>compatible with any C compilers' and meet the requirement
>that way.

So let them (that way, users will be warned away from such compilers).
For extern "C" to have any meaning at all, it must mean "this function is
assumed to obey the conventions of C functions provided by <some C
compiler>".  Remember that not all C compilers for a given platform
necessarily produce completely interoperable code.

In any case, many common compiler packages provide both C and C++
compilation in a compatible way (Borland, Microsoft, GNU, and about every
Unix C++ compiler I know of), or are by construction compatible with an
available C compiler (cfront).  This compatibility is generally strong
enough that the only difference between C and C++ is name mangling (so the
qsort problem is not a problem in practice).  One question to be addressed
is whether extern "C" could refer to a completely different convention for
argument-passing, in which case qsort is a problem, function pointers need
an extern "C" tag, etc.  But even if this convention can be different, it
still must correspond to a particular [set of] C compiler[s].

--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Anagrams for "information superhighway": Enormous hairy pig with fan
      A rough whimper of insanity





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/08/02
Raw View
In article <KANZE.95Jul25103036@slsvhdt.lts.sel.alcatel.de>,
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:

>May I ask a question: why all these worries about qsort?  Why not just
>use sort (section 25.3.1.1)?  It is more flexible, and the benchmarks
>I've see suggest it is (as is to be expected) faster.

 I agree completely with James. "qsort" is there for
C compatibility.

 DONT USE IT!

 It isn't clear it is POSSIBLE to use qsort.
Suppose extern "C" functions use a DIFFERENT calling convention.

 Question 1: what is the calling convention of a function passed
to such a function -- C or C++? Answer: C because otherwise qsort
would not work.

 Question 2: can you compile an extern "C" function in C++?
Answer: not necessarily.

 Question 3: can you call code compiled with a C compiler?
Answer: not necessarily.


 Result: qsort may not be useable: it has to be there,
it doesn't have to be useful. You certainly can't assume at this
point in time any use of it will be portable. The final Standard
might provide better guarrantees, but I have doubts.
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/02
Raw View
greghunt@zeta.org.au writes:

> We are not attempting to support linkage between compilers - which is
> both unfortunate and too hard - but we have the prospect of different
> linkages being generated by the same compiler at different times -
> which seems unnecessary.

That is a *very* good point.

Regardless of whether or not a C++ compiler is or is not required to
support interfacing with C, a stand-alone C++ program may contain
"C" linkage-specifications.  The C++ standard *must* make it clear
whether or not a program such as the following is strictly conforming.

 void foo(void (*func)()) { (*func)(); }
 void bar() {}
 extern "C" void baz() {}

 int main() {
  foo(bar);
  foo(baz);
  return 0;
 }

According to my reading of the ARM and the current draft standard, this
program is strictly conforming.  The semantics of the `foo(baz)' are
well-defined for exactly the same reason that the semantics of `foo(bar)' are
well-defined.

I think it would be a bad mistake if there committee were to decide to
disallow this program, or give it undefined behaviour.
It would break a significant amount of code and impose a continuing
hardship on C++ programmers, with very few compensating benefits.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/08/03
Raw View
In article <DCn5qw.94G@research.att.com> ark@research.att.com (Andrew
Koenig)  writes:
> In article <1995Aug1.105954.1403@ittpub> wil@ittpub.nl (Wil Evers)
writes:
>
> > I can't understand why the committee is having such a hard time over
this
> > issue. Why not just require a C++ implementation to specify with which
C
> > compiler(s) (and versions) it is compatible on a given platform?
>
> Such a requirement is uninteresting, because
> a vendor can simply say `Our C++ implementation is not
> compatible with any C compilers' and meet the requirement
> that way.

Why would such a statement be uninteresting? If I was looking for a decent
C++ compiler, I'd be more than interested.

- Wil





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/08/03
Raw View
Andrew Koenig (ark@research.att.com) wrote:
|> In article <1995Aug1.105954.1403@ittpub> wil@ittpub.nl (Wil Evers) writes:

|> > I can't understand why the committee is having such a hard time over this
|> > issue. Why not just require a C++ implementation to specify with which C
|> > compiler(s) (and versions) it is compatible on a given platform?

|> Such a requirement is uninteresting, because
|> a vendor can simply say `Our C++ implementation is not
|> compatible with any C compilers' and meet the requirement
|> that way.

Actually, I don't think that that was the point.  What was requested was
that the C++ vendor be required to specify this fact, rather than
letting us find it out by trial and error.

Still, they could always specify that their C++ compiler was compatible
with the GABI Software C compiler version 1.0.  Of course, since I'm not
in the process of writing a compiler, it's hard to say when this C
compiler will be released.  So I'm not sure what good this information
will do you.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
                             --Beratung in industrieller Datenverarbeitung





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/08/03
Raw View
In article <MATT.95Aug1101128@godzilla.EECS.Berkeley.EDU>
matt@physics.berkeley.edu writes:
> In article <3vlhsd$s3i@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve
Clamage) writes:
>
> > >I can't understand why the committee is having such a hard time over
this
> > >issue. Why not just require a C++ implementation to specify with
which C
> > >compiler(s) (and versions) it is compatible on a given platform?
> >
> > Let's suppose the committee makes exactly that requirement. Your C++
> > compiler manual says "This C++ compiler is compatible with the XYZ C
> > compiler, version 2.0.2," thus complying with the requirement. Are you
now
> > better off than you were before?
>
> To expand on Steve's points: what happens if XYZ corporation stops
> selling version 2.0.2 of its compiler?  Does that mean that your C++
> compiler is no longer standard-conforming?  Or what happens if you
> want to write a C++ compiler for a platform for which there isn't any
> C compiler?  (That's not as artificial a what-if as you might think:
> don't forget embedded systems.)
>
> C and C++ are different languages.  I just don't see that cross-language
> compatibility are within the scope of the C++ standard.

I'm still puzzled. Obviously, extern "C" (or, for that matter, extern
"SomeObscureLanguage") is in C++ right now and users depend on it, so it
is here to stay. This implies that the standard will have to phrase *some*
set of requirements about what it does. The question thus becomes what the
standard should require. Here's an informal attempt:

- The standard should require the compiler vendor to specify what forms of
external linkage are supported. At the very least, extern "C" and extern
"C++" must be supported.

- For each of these forms of external linkage, the standard should require
the compiler vendor to specify which name encoding scheme and calling
conventions are used. As Steve Clamage pointed out, such a requirement
could be satisfied by to referring to some well-defined ABI. For extern
"C", 'same as C compiler XYZ version 2.0.2' would be good enough, as long
as that compiler defines its name encoding scheme and calling conventions.

- For extern "C", the standard could say that the calling conventions must
the same as for extern "C++", which was my original point. The benefit of
this would be that pointers to extern "C" and extern "C++" functions are
assignment compatible.

- For other linkages forms, the standard could require the use of a
typedef to declare pointers to such functions, and specify that such
pointers are not assignment compatible accross different linkages:

typedef extern "XXX" void (*PXXXF)();
extern "YYY" void f();
PXXXF p = f;  // error: incompatible linkage

- Wil





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/08/03
Raw View
In article 1415@ittpub, wil@ittpub.nl (Wil Evers) writes:
>
>- The standard should require the compiler vendor to specify what forms of
>external linkage are supported. At the very least, extern "C" and extern
>"C++" must be supported.

That is already the case. "C" and "C++" linkage must be supported.


>- For each of these forms of external linkage, the standard should require
>the compiler vendor to specify which name encoding scheme and calling
>conventions are used. As Steve Clamage pointed out, such a requirement
>could be satisfied by to referring to some well-defined ABI. For extern
>"C", 'same as C compiler XYZ version 2.0.2' would be good enough, as long
>as that compiler defines its name encoding scheme and calling conventions.

Now things get stickier. It's fine for you to say "name encoding scheme"
and "calling conventions". But the standard would have to define what
that means. What if there is no linker and no name encoding? What
exactly must be specified in "calling conventions": Register usage? There
might not be any registers. Stack frame layout? There might not be a stack
frame, or even a stack as it is commonly thought of.

The standard would have to say what the vendor must specify, but without
reference to hardware features which might not exist, and possibly missing
things which would be important on some platform. This stikes me as
a losing game. As I said before, what you want is an ABI, and specifying
an ABI, or even what an ABI must contain, is outside the scope of a
programming language standard. (Take a look at the Unix SVR4 ABI, for
example, and then notice it contains no hardware-sepcific data. You need
another document that gives the ABI details for the specific processor.)

Please also notice that you have been focusing so much on function linkage
that you have not mentioned things like commonality of data types: are ints
the same size and format with both compilers? Pointers? Do the compilers
use the same data alignment algorithm? And so on. These are at least as
important as function linkage, and are part of an ABI.

We cannot solve all problems with a language standard. Some people would
like the standard to be specific enough that any compiler that met its
requirements would be useful and efficient. IMHO, this can't be done,
and isn't worth trying to do. (If someone wants to spend several
person-years producing a C++ implementation that meets all the requirements
of the standard yet is useless, that's OK with me. But I won't buy it.)

As I said before, a C++ compiler vendor must, out of self-interest, strive
for compatibility with other popular systems, and document that
compatibility -- whether the standard says so or not.
---
Steve Clamage, stephen.clamage@eng.sun.com







Author: ark@research.att.com (Andrew Koenig)
Date: 1995/08/03
Raw View
In article <1995Aug3.110213.1412@ittpub> wil@ittpub.nl (Wil Evers) writes:

> > Such a requirement is uninteresting, because
> > a vendor can simply say `Our C++ implementation is not
> > compatible with any C compilers' and meet the requirement
> > that way.

> Why would such a statement be uninteresting? If I was looking for a decent
> C++ compiler, I'd be more than interested.

But your interest would be the same whether the Standard
said anything about it or not.  That's the point.
--
    --Andrew Koenig
      ark@research.att.com





Author: imp@village.org (Warner Losh)
Date: 1995/08/03
Raw View
In article <3vo9lr$los@metro.ucc.su.oz.au>,
John Max Skaller <maxtal@Physics.usyd.edu.au> wrote:
> It isn't clear it is POSSIBLE to use qsort.
>Suppose extern "C" functions use a DIFFERENT calling convention.

This sounds like another of the committee's unwise calls.  I do
understand the issues behind it, however, there is some legacy code
that depends on being able to call qsort from C++.

> Result: qsort may not be useable: it has to be there,
>it doesn't have to be useful. You certainly can't assume at this
>point in time any use of it will be portable. The final Standard
>might provide better guarrantees, but I have doubts.

This is the part that worries me the most.  Traditionally, you've been
able to do this, and as far as I know it works on all existing
compilers (at least the major ones I've used).  Breaking this now
isn't the best possible service that the committee could do to the
application developers (although it does let the compiler writers off
the hook more easily).

IMHO, if qsort is part of the language, then it must be possible to
write extern "C" functions in C++ and have the compiler cope.  After
all, it *KNOWS* that the function is extern "C", so it should know
enough to have it follow the 'C' ABI should it differ from the C++
ABI.

This isn't the more subtle issue of what that ABI actually is, merely
a requirement that C++ functions that have "C" linkage must follow
whatever ABI that the compiler uses for those functions.  Right now
the compiler must be able to correctly call these functions (if it
supports a "C" ABI).  It would seem prudent to require that the
compiler generate callable functions as well as calls to functions.

Or have I missed something subtle in this thread?

Warner
--
Warner Losh  "VMS Forever"  home: imp@village.org
Cyberspace Development, Inc   work: imp@marketplace.com
Makers of TIA, The Internet Adapter.  http://marketplace.com/





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/03
Raw View
ark@research.att.com (Andrew Koenig) writes:

>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>> [...] requiring C++ compilers to use the same calling convention as the
>> underlying C compiler is still an option that is very much open to
>> the committee.
>
>The committee has discussed this issue on and off for years,
>and no one has yet proposed a satisfactory solution.
>
>Here are a few questions that should help point out why this is a
>hard problem:
>
> 1. Suppose you have two mutually incompatible C compilers on
> your machine?  Is every C++ compiler required to be compatible
> with both of them?

No, it clear that simply loading a new C compiler onto your hard disk
should not suddenly make your C++ compiler non-conforming.

> If not, suppose your C++ compiler is compatible
> with only one of them and you remove that C compiler.  Does that
> invalidate the C++ compiler?

Suppose your hard disk crashes.  Does that invalidate the C++ compiler?

(I think I've got the hang of a questions arms-race now ;-)

Let me answer my question first, and then yours.  If I have Foobar C++
on my hard disk, and it crashes, that does not mean that Foobar C++ is
not a conforming C++ implementation.  To be pedantic, talking about
whether or not Foobar C++ is a conforming implementation is a
convenient simplification which breaks down in this situation.  Really
we ought to only talk about the conformance of a particular computer
system ("processor", to use the draft standard's terminology) --
comprising of not just software, but also hardware and documentation.
If my hard disk crashes, then the computer system sitting on my desk is
not conforming, but of course Foobar C++ may still be part of some
other conforming computer system whose hard drive has not crashed, and
Foobar Inc. are certainly still justified in claiming that their
product conforms to the standard.

Now, suppose the C++ standard were to require that C++ implementations
support interfacing to C.  Pedantically, you still can't talk about
whether Foobar C++ is conforming; you have to talk about the
conformance of a whole computer system.  If the C++ standard were to
require implementations to support interfacing to C, then said computer
system must clearly include a C compiler (or interpreter, etc.).
Foobar C++ can still certainly claim conformance to the standard, even
if it does not come packaged with a C compiler.  After all, it doesn't
come packaged with a machine to run it on either!  Instead, there is
usually a little note on the box - "requires an IBM compatible with a
386 or better and at least 8M of RAM and 100M of disk space, running
Microsoft Windows" or something similar.  If Foobar C++ also requires
Quux C to support the requirements in the C++ standard about
interfacing to C, then they should document that too - but they can
certainly still claim conformance to the standard.

As before, if I remove the C compiler from my hard drive, or if my hard
drive crashes, or if the power supply suddenly dies with a loud bang
and a big cloud of black smoke (this has happened to me! ;-), then the
computer system on my desk no longer comprises a "conforming
processor", according to the definition in the C++ standard.  But that
doesn't affect the right of Foobar Inc. to claim conformance with the
C++ standard.

> 2. Suppose the C compiler vendor changes linkage conventions
> incompatibly.  Does that invalidate the C++ compiler?

Supposing the OS vendor changes linkage conventions incompatibly [*].
Does that invalidate the C++ compiler?

 [*] This is not just hypothetical.  SGI changed the linkage
 conventions incompatibly between Irix 4.x and 5.0.  When our
 site upgraded, it broke the compiler (for Mercury, not C++)
 that I and my colleagues have been writing.  Fixing it was
 a decidedly non-trivial undertaking.

The answer to these questions is the same as before.
The Foobar C++ documentation should state which version(s) of the
the Quux C compiler and which version(s) of the linker, program loader,
extended/expanded/ex-whatever memory manager, shell, and OS (and
any other software with which it must interact) it supports.
Obviously if you change any of the software in the computer system,
it may cause the resulting system to fail to be compliant.
But that is not Foobar Inc.'s fault.

>In both these cases, the question `Does that invalidate the C++ compiler'
>means `Does the vendor of this C++ compiler lose the right to claim that
>that compiler conforms to the standard?'
>
>If the answer is `yes,' that means that in effect one can produce a
>standard-conforming C++ compiler only by permission of the C compiler
>vendors for that machine.

I don't agree.  Even if a standard-conforming C++ "processor" must
include a C compiler, that does not implies that the vendor of a
stand-alone C++ compiler cannot claim conformance with the standard.
Clearly a C++ compiler does not on its own constitute a
standard-conforming C++ "processor".  For that, you need at the very
least an OS and a machine to run it on.  I don't think it would be
unreasonable for the standard to require such a processor to also
include a C compiler.

>If the answer is `no,' it is hard to see how
>to write a requirement for compatibility.

The way it is done in the Ada 95 standard seems satisfactory to me -
perhaps not ideal, but certainly much better than throwing up our hands in
defeat in the belief that such a requirement cannot be phrased.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: greghunt@zeta.org.au
Date: 1995/07/30
Raw View
Why is a C++ compiler required to generate code that is compatible with ANY C compiler at
all?

It looks rather as though what this means needs to be spelt out in the draft a bit more clearly.

Does extern "C" enable linking to code produced by an ANSI C compiler that exists somewhere
in the world?  Then the section in the draft needs to say something like that.  If it just relates
to names in object (or at least to type safe linkage) then there probably doesn't need to be any
change.

I think that at least some of us will go mad with out some sort of rationale docment to
explain these sorts of points because performing conceptual set operations on the comments
in the ARM, D+E and the draft in order to work out what something is and then why
something is, is:
   a) hard
   b) prone to argument
   c) frustrating.

The most common need seems to be to link code from a C++ compiler from a specific vendor
with code from a C compiler from the same vendor.  Aren't we talking about having to add
decorations to code from ONE compiler so that it can be called safely by code from the same
compiler?






Author: wil@ittpub.nl (Wil Evers)
Date: 1995/08/01
Raw View
In article <DCErIA.IJt@research.att.com> ark@research.att.com (Andrew
Koenig) writes:
> In article <9520904.20645@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
(Fergus Henderson) writes:
>
> > The ARM and the draft standard are certainly not clear on the issue,
> > and requiring C++ compilers to use the same calling convention as the
> > underlying C compiler is still an option that is very much open to
> > the committee.
>
> The committee has discussed this issue on and off for years,
> and no one has yet proposed a satisfactory solution.
>
> Here are a few questions that should help point out why this is a
> hard problem:
>
>  1. Suppose you have two mutually incompatible C compilers on
>  your machine?  Is every C++ compiler required to be compatible
>  with both of them?  If not, suppose your C++ compiler is
compatible
>  with only one of them and you remove that C compiler.  Does that
>  invalidate the C++ compiler?
>
>  2. Suppose the C compiler vendor changes linkage conventions
>  incompatibly.  Does that invalidate the C++ compiler?
>
> In both these cases, the question `Does that invalidate the C++
compiler'
> means `Does the vendor of this C++ compiler lose the right to claim that
> that compiler conforms to the standard?'
>
> If the answer is `yes,' that means that in effect one can produce a
> standard-conforming C++ compiler only by permission of the C compiler
> vendors for that machine.  If the answer is `no,' it is hard to see how
> to write a requirement for compatibility.

I can't understand why the committee is having such a hard time over this
issue. Why not just require a C++ implementation to specify with which C
compiler(s) (and versions) it is compatible on a given platform?

- Wil






Author: pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428)
Date: 1995/07/28
Raw View
In article <u9ivorlolb.fsf@phydeaux.cygnus.com>, jason@cygnus.com (Jason Merrill) writes:
-->>>>>> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
-->
-->>> clamage@Eng.Sun.COM wrote:
-->>>
-->>>> Section 25.4:
-->>>>
-->>>> " void qsort(void* base, size_t nmemb, size_t size,
-->>>> int (*compar)(const void*, const void*));
-->>>>
-->>>> the function argument compar shall have extern "C" linkage (7.5).
-->>>> Also, since compar() may throw an exception, qsort() is allowed to
-->>>> propagate the exception (17.3.4.8). "
-->
-->> This is a serious incompatibility with C, since it makes it impossible
-->> to pass the address of a static function to qsort().
-->
-->No, it doesn't.
-->
-->extern "C" {
-->  static int qsort_callback (const void *, const void *) { ... }
-->}

It stinks doesn't it!  Why not allow

    static "C" int qsort_callback ...

?

Anyway, enough quibbling.  Do I understand from this discussion that

** (A) ** In ANSI C++ there will be no way to declare a pointer to a function
with non-C++ linkage.

I'm sure I've used the following successfully.

    extern "C"
        {
        typedef int (*qsort_callback) (const void *, const void *);
        };

Why has the committee rejected this obvious (if clumsy) solution?


(and again why not allow

    typedef "C" ...

?)

** (B) ** qsort is given special dispensation and that in general there
will be no way to pass a function pointer to a function implemented in C.
This will severely restrict the use of third-party libraries.

As for compar() being allowed to throw an exception, I can't help feeling
that this is somewhat dangerous.  Will it really be possible to implement
an exception mechanism that can throw exceptions over the activation frames
of extern "C" functions?  I would have thought it safer to rule that
no function with "C" linkage (even if written in C++) can throw any exception --
i.e. there's an implicit "throw ()" there.

-- jP --







Author: chase@centerline.com (David Chase)
Date: 1995/07/28
Raw View
pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428) writes:

> Will it really be possible to implement an exception mechanism that can
> throw exceptions over the activation frames of extern "C" functions?

Possible?  Done already, several different ways.  Sun's exception
dispatcher does this by default, I believe, and the
setjmp/longjmp/runtime-registration implementation trivially skips frames
that do not register themselves (that is, they can appear to raise
anything).  I think it many cases it would actually be harder to write
one that did not do this (i.e., one that would complain if you tried
to throw an exception over a C function's activation record).

speaking for myself,

David Chase





Author: huber@kazoo.cs.uiuc.edu (Jay Huber)
Date: 1995/07/28
Raw View
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:

>>clamage@Eng.Sun.COM wrote:
>>
>>> Section 25.4:
>>>
>>> " void qsort(void* base, size_t nmemb, size_t size,
>>>         int (*compar)(const void*, const void*));
>>>
>>> the function argument compar shall have extern "C" linkage (7.5).
>>> Also, since compar() may throw an exception, qsort() is allowed to
>>> propagate the exception (17.3.4.8). "
>
>This is a serious incompatibility with C, since it makes it impossible
>to pass the address of a static function to qsort().


But giving a function extern "C" linkage does not give the function
external linkage.  For example,

extern "C" void f();

static void f() { cout << "ok" << endl; }

Here, f has extern "C" linkage, but is not external.  It cannot
be referneced from another module.  Take out the 'static' and it can.

The above example works with CodeWarrior 6, but I'm unable to tell
by reading the ARM if the example is correct.


Jay Huber
huber@kazoo.cs.uiuc.edu






Author: ark@research.att.com (Andrew Koenig)
Date: 1995/07/28
Raw View
In article <9520904.20645@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:

> The ARM and the draft standard are certainly not clear on the issue,
> and requiring C++ compilers to use the same calling convention as the
> underlying C compiler is still an option that is very much open to
> the committee.

The committee has discussed this issue on and off for years,
and no one has yet proposed a satisfactory solution.

Here are a few questions that should help point out why this is a
hard problem:

 1. Suppose you have two mutually incompatible C compilers on
 your machine?  Is every C++ compiler required to be compatible
 with both of them?  If not, suppose your C++ compiler is compatible
 with only one of them and you remove that C compiler.  Does that
 invalidate the C++ compiler?

 2. Suppose the C compiler vendor changes linkage conventions
 incompatibly.  Does that invalidate the C++ compiler?

In both these cases, the question `Does that invalidate the C++ compiler'
means `Does the vendor of this C++ compiler lose the right to claim that
that compiler conforms to the standard?'

If the answer is `yes,' that means that in effect one can produce a
standard-conforming C++ compiler only by permission of the C compiler
vendors for that machine.  If the answer is `no,' it is hard to see how
to write a requirement for compatibility.
--
    --Andrew Koenig
      ark@research.att.com





Author: jjb@watson.ibm.com (John Barton)
Date: 1995/07/29
Raw View
I don't think this thread has gotten disgusting enough yet ;-).
Consider, if you dare, that major vendors may well
implement the ability to call functions on objects in
other languages, eg SOM, CORBA, COM and to call functions
on objects implemented by popular compilers.  This will likely
be done by some kind of language extension.  This is the OO
version of the problem that linkage set out to solve and it
is a problem that needs a standard solution.

--
John.

John J. Barton        jjb@watson.ibm.com            (914)784-6645
 <http://www.research.ibm.com/xw-SoftwareTechnology>
H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/27
Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:

>May I ask a question: why all these worries about qsort?  Why not just
>use sort (section 25.3.1.1)?

`qsort' is just one example of a general problem.

The same type of problem will come up in all sorts of situations, for
example X call-backs, signal handlers, the finalization interface to
the Boehm garbage collector, etc. etc. etc.

Like it or not, interfacing to C will remain important for a long time
to come.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/27
Raw View
>wil@ittpub.nl (Wil Evers) writes:
>>
>>I know it's late, but with hindsight, allowing a C++ compiler to use
>>different calling conventions from the underlying C compiler was probably
>>a mistake. Sure, it may save us a few CPU cycles here and there, but to
>>me, the price (an even more complicated pointer to function syntax) is
>>simply too high. The language is hard enough to understand without it.

I agree with you, except for one thing: you should use a future tense,
not the past tense.

The ARM and the draft standard are certainly not clear on the issue,
and requiring C++ compilers to use the same calling convention as the
underlying C compiler is still an option that is very much open to
the committee.

(Or at least it was before last week's committee meeting in Monteroy;
I don't know whether they made a decision on this topic then.)

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: greghunt@zeta.org.au
Date: 1995/07/27
Raw View
You asked why all these worries about qsort?

I got into this thread by suggesting (early in the life of the thread) that the main
effect of a linkage specification was in altering the name used in the generated
object code rather than specifying different instruction sequences.  I subsequently
found a paragraph in "the Design and Evolution..." which said just that.

I am not concerned with qsort in particular.  I am a little perturbed by the
idea that one compiler may generate different function prologue and epilog sequences
(distinguishable because the programmer may be required to identify them when they
are entered as a result of a call to a function through a pointer - the linkage specification)
which must otherwise both support the same behaviours (Exceptions etc).  This seems
unnecessary.

We are not attempting to support linkage between compilers - which is
both unfortunate and too hard - but we have the prospect of different linkages being
generated by the same compiler at different times - which seems unnecessary.







Author: tony@online.tmx.com.au (Tony Cook)
Date: 1995/07/27
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: In article 1807951030140001@bill-law.taligent.com, bill_law@taligent.com (William A. Law) writes:
: ....
: >Thank you.  I see that this addresses only qsort; will similar notes be
: >attached for each of the other functions in the standard library that take
: >pointer-to-function arguments?

: The only other C library function which takes a callback is bsearch, and
: the draft has similar wording about C linkage for that function.

And signal.
--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/28
Raw View
neeri@iis.ee.ethz.ch (Matthias Neeracher) writes:

>How about a different syntax:
>
>int (extern "C" * fp2)() = c_func;
>
>Having "extern" in the middle of a declaration might look somewhat ugly, but
>this solution [... has lots of advantages ..]

Do we even need the `extern'?  What about using just a string literal?
Would this cause any parsing problems?

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/26
Raw View
In article <3v00nc$d69@godzilla.zeta.org.au> greghunt@zeta.org.au (Greg
Hunt) writes:
> In <1995Jul20.173028.1375@ittpub>, wil@ittpub.nl (Wil Evers) writes:
> >
> >I know it's late, but with hindsight, allowing a C++ compiler to use
> >different calling conventions from the underlying C compiler was
probably
> >a mistake. Sure, it may save us a few CPU cycles here and there, but to
> >me, the price (an even more complicated pointer to function syntax) is
> >simply too high. The language is hard enough to understand without it.
> >
> >- Wil
>
> Where is this decision documented?  In D+E, B Stroustrup talks about the
> behaviour being identical for extern "C" and extern "C++" functions.
>
>   "The linkage specification does not affect the semantics of the
program
>   using sqrt() but simply tells the compiler to use the C naming
conventions
>   for the name used for sqrt() in the object code."
>
>     The Design and Evolution of C++, page 234.
>
> The draft standard is not so clear on the subject and the discussion on
the
> following page in D+E about the linkage of pointers I had always found
rather
> puzzling because it seemed to appear out of thin air and had assumed
that it
> related to matching parameter lists in the source code rather than
execution
> characteristics.
>



Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/26
Raw View
In article <MATT.95Jul24104745@godzilla.EECS.Berkeley.EDU>
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
> In article <1995Jul20.173028.1375@ittpub> wil@ittpub.nl (Wil Evers)
writes:
>
> > I know it's late, but with hindsight, allowing a C++ compiler to use
> > different calling conventions from the underlying C compiler was
probably
> > a mistake. Sure, it may save us a few CPU cycles here and there, but
to
> > me, the price (an even more complicated pointer to function syntax) is
> > simply too high. The language is hard enough to understand without it.
>
> I don't think there's any choice about that decision: there's no
> guarantee that any particular C++ implementation has an underlying C
> compiler at all.  In fact, most C++ implementations that I'm aware of
> compile C++ directly to machine code without ever passing though C.
>
> It's likely that most programmers out there have one or more C
> compilers on their machines, but what good is that from the point of
> view of the C++ standard?  How could we conceivably word a requirement
> about interoperability between a C++ implementation and some other
> random C implementation?  That's totally outside the scope of a
> language standard.

I shouldn't have said ``underlying C compiler'' but something like ``a
compiler that's capable of generating code for functions that have extern
"C" linkage in a given C++ implementation.'' Obviously, the C++ compiler
must know which name encoding scheme and calling conventions to use for
extern "C" functions, so this other compiler is not a random one, but one
the C++ compiler is intimately aware of. It may even be the same compiler.
I'm not a language lawyer, but I think some phrase in the standard saying
that a function's linkage is irrelevant when its address is taken would
effectively enforce the same calling conventions for both compilers.

- Wil





Author: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/07/24
Raw View
In article <1995Jul20.173028.1375@ittpub> wil@ittpub.nl (Wil Evers) writes:

> I know it's late, but with hindsight, allowing a C++ compiler to use
> different calling conventions from the underlying C compiler was probably
> a mistake. Sure, it may save us a few CPU cycles here and there, but to
> me, the price (an even more complicated pointer to function syntax) is
> simply too high. The language is hard enough to understand without it.

I don't think there's any choice about that decision: there's no
guarantee that any particular C++ implementation has an underlying C
compiler at all.  In fact, most C++ implementations that I'm aware of
compile C++ directly to machine code without ever passing though C.

It's likely that most programmers out there have one or more C
compilers on their machines, but what good is that from the point of
view of the C++ standard?  How could we conceivably word a requirement
about interoperability between a C++ implementation and some other
random C implementation?  That's totally outside the scope of a
language standard.
--
  Matt Austern                             He showed his lower teeth.  "We
  matt@physics.berkeley.edu                all have flaws," he said, "and
  http://dogbert.lbl.gov/~matt             mine is being wicked."





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/24
Raw View
>clamage@Eng.Sun.COM wrote:
>
>> Section 25.4:
>>
>> " void qsort(void* base, size_t nmemb, size_t size,
>>         int (*compar)(const void*, const void*));
>>
>> the function argument compar shall have extern "C" linkage (7.5).
>> Also, since compar() may throw an exception, qsort() is allowed to
>> propagate the exception (17.3.4.8). "

This is a serious incompatibility with C, since it makes it impossible
to pass the address of a static function to qsort().

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/07/24
Raw View
>>>>> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:

>> clamage@Eng.Sun.COM wrote:
>>
>>> Section 25.4:
>>>
>>> " void qsort(void* base, size_t nmemb, size_t size,
>>> int (*compar)(const void*, const void*));
>>>
>>> the function argument compar shall have extern "C" linkage (7.5).
>>> Also, since compar() may throw an exception, qsort() is allowed to
>>> propagate the exception (17.3.4.8). "

> This is a serious incompatibility with C, since it makes it impossible
> to pass the address of a static function to qsort().

No, it doesn't.

extern "C" {
  static int qsort_callback (const void *, const void *) { ... }
}

Jason





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/07/25
Raw View
In article <3v011l$d69@godzilla.zeta.org.au> greghunt@zeta.org.au
writes:

|> In <3usgs3$rhi@godzilla.zeta.org.au>, greghunt@zeta.org.au writes:

|> >>>>> sorry about the formatting of the previous post - new news reader...

|> What I had said was:

|> Can someone point me to a place in the draft where a functional
|> specification of these linkages resides?  What their execution
|> characteristics MUST support?  I am curious to know what we get by
|> allowing the function prologues and epilogs to be incompatible between C
|> and C++ executables from the same compiler.

|> It seems that extern "C" functions that can throw exceptions.  While
|> thinking about this issue in the shower this morning exception handling
|> seemd to be the reason for allowing C and C++ linkage to be functionally
|> different.  So much for that good idea.

|> Do I read the doc aright as saying that qsort may throw any exception or
|> is there a constrained list of exceptions that can be thrown?

The semantics of qsort are defined by the C standard.  Thus, the qsort
code itself cannot throw an exception.  On the other hand, qsort calls
a user defined call-back function; this function can throw any
exception it wants, and this exception will propagate back through
qsort to qsort's caller.  Thus: qsort can throw any exception, but as
user, you can control which exceptions it will actually throw (those
thrown by your call-back function).

May I ask a question: why all these worries about qsort?  Why not just
use sort (section 25.3.1.1)?  It is more flexible, and the benchmarks
I've see suggest it is (as is to be expected) faster.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: greghunt@zeta.org.au
Date: 1995/07/23
Raw View
Can someone point me to a place in the draft where a functional specification of these linkages resides?  What their execution characteristics MUST support?  I am curious to know what we get by allowing the function prologues and epilogs to be incompatible between C and C++ executables from the same compiler.

It seems that extern "C" functions that can throw exceptions.  While thinking about this issue in the shower this morning exception handling seemd to be the reason for allowing C and C++ linkage to be functionally different.  So much for that good idea.

Do I read the doc aright as saying that qsort may throw any exception or is there a constrained list of exceptions that can be thrown?





Author: tony@online.tmx.com.au (Tony Cook)
Date: 1995/07/23
Raw View
greghunt@zeta.org.au wrote:
: In <3tuqce$7c4@silver.jba.co.uk>, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
: >Quick question for you all :
: >
: >    When you include the <cstdlib> header within your program, the
: >    qsort() function is declared.  What is the linkage of the function
: >    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
: >

: I think that the use of the term linkage is a bit problematic...

: The linkage referred to by the standard is linkage editor type
: linkage - what the function name gets mashed to in the generated
: object code.  It isn't the sequence of instructions that are executed
: as part of the routine prolog and epilog.  It is possible for
: a routine with one the same prolog and epilog instruction sequence to
: have different linkage editor linkage (different name mangling) in
: different instances and for it to be callable through a pointer regardless
: of the naming.

An annotation in the ARM made it pretty clear that linkage in terms
of linkage specifications also included the calling sequence of the
function.  The WP doesn't seem to, but it does say that there may be
a difference between pointers to C++ functions and pointers to
functions written in other languages ("taking address ... is
undefined").
--
        Tony Cook - tony@online.tmx.com.au
                    100237.3425@compuserve.com





Author: greghunt@zeta.org.au
Date: 1995/07/24
Raw View
In <1995Jul20.173028.1375@ittpub>, wil@ittpub.nl (Wil Evers) writes:
>
>I know it's late, but with hindsight, allowing a C++ compiler to use
>different calling conventions from the underlying C compiler was probably
>a mistake. Sure, it may save us a few CPU cycles here and there, but to
>me, the price (an even more complicated pointer to function syntax) is
>simply too high. The language is hard enough to understand without it.
>
>- Wil

Where is this decision documented?  In D+E, B Stroustrup talks about the
behaviour being identical for extern "C" and extern "C++" functions.

  "The linkage specification does not affect the semantics of the program
  using sqrt() but simply tells the compiler to use the C naming conventions
  for the name used for sqrt() in the object code."

    The Design and Evolution of C++, page 234.

The draft standard is not so clear on the subject and the discussion on the
following page in D+E about the linkage of pointers I had always found rather
puzzling because it seemed to appear out of thin air and had assumed that it
related to matching parameter lists in the source code rather than execution
characteristics.

Greg Hunt





Author: greghunt@zeta.org.au
Date: 1995/07/24
Raw View
In <3usgs3$rhi@godzilla.zeta.org.au>, greghunt@zeta.org.au writes:

>>>>> sorry about the formatting of the previous post - new news reader...

What I had said was:

Can someone point me to a place in the draft where a functional
specification of these linkages resides?  What their execution
characteristics MUST support?  I am curious to know what we get by
allowing the function prologues and epilogs to be incompatible between C
and C++ executables from the same compiler.

It seems that extern "C" functions that can throw exceptions.  While
thinking about this issue in the shower this morning exception handling
seemd to be the reason for allowing C and C++ linkage to be functionally
different.  So much for that good idea.

Do I read the doc aright as saying that qsort may throw any exception or
is there a constrained list of exceptions that can be thrown?


Greg Hunt





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/18
Raw View
In article 1807951030140001@bill-law.taligent.com, bill_law@taligent.com (William A. Law) writes:
>In article <3uej90$8t7@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM wrote:
>
>> Section 25.4:
>>
>> " void qsort(void* base, size_t nmemb, size_t size,
>>         int (*compar)(const void*, const void*));
>>
>> the function argument compar shall have extern "C" linkage (7.5).  Also, since
>> compar() may throw an exception, qsort() is allowed to propagate the exception
>> (17.3.4.8). "
>
>Thank you.  I see that this addresses only qsort; will similar notes be
>attached for each of the other functions in the standard library that take
>pointer-to-function arguments?

I recommend that you pick up a copy of the draft, available in html for
easy browsing with a Web browser, or a PDF vesion usable with the free
Adobe Acrobat reader.

The only other C library function which takes a callback is bsearch, and
the draft has similar wording about C linkage for that function.

Such language linkage is an issue only for the C library, since C++
library functions are expected to have and use C++ linkage.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: bill_law@taligent.com (William A. Law)
Date: 1995/07/18
Raw View
In article <3uej90$8t7@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM wrote:

> Section 25.4:
>
> " void qsort(void* base, size_t nmemb, size_t size,
>         int (*compar)(const void*, const void*));
>
> the function argument compar shall have extern "C" linkage (7.5).  Also, since
> compar() may throw an exception, qsort() is allowed to propagate the exception
> (17.3.4.8). "

Thank you.  I see that this addresses only qsort; will similar notes be
attached for each of the other functions in the standard library that take
pointer-to-function arguments?

Bill





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/19
Raw View
In article <3uej90$8t7@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve
Clamage) writes:

[snip]

> A suggestion
> is to handle language linkage similarly to a throw specification: it
> isn't part of the function type, but you can specify it on a pointer
> declaration. The exact syntax and semantics haven't been worked out,
> but we might wind up with something like this:
>
>  extern "C" int c_func();
>  int (*fp1)() = c_func; // error: c_func doesn't have C++ linkage
>  extern "C" int (*fp2)() = c_func; // ok
>
> In the last line, the 'extern "C"' would specify the linkage of
functions
> that fp2 can point to. I don't know how function parameters like
"compar"
> would be specified.

This looks confusing to me. How would we distinguish between the linkage
of the function pointed to and the linkage of the pointer itself? If you
ask me,

extern int (*fp2)();

means the pointer fp2 has external linkage, not the function it points to.
Does this mean that a pointer with external linkage pointing to a function
with extern "C" linkage would look like

extern extern "C" int (*fp2)();

or something like that?

- Wil





Author: Michael Cook <mcook@cognex.com>
Date: 1995/07/19
Raw View
>>>>> "MN" == Matthias Neeracher <neeri@iis.ee.ethz.ch> writes:

 MN> How about a different syntax:

 MN> int (extern "C" * fp2)() = c_func;

To be consistent with the qualifiers const and volatile, the syntax could be

  int (* extern "C" fp2)();          // fp2 has extern "C" linkage,
                                     // *fp2 has extern "C++" linkage.
  extern "C" int (*fp3)();           // fp3 has extern "C++" linkage,
                                     // *fp3 has extern "C" linkage.
  extern "C" int (*extern"C"fp4)();  // fp4 and *fp4 have extern "C" linkage.

So then how would we declare a static pointer to an extern"C" function?

  extern "C" int (*static fp4)();

Hmm.  That's probably sufficiently confusing...

Michael.





Author: bill_law@taligent.com (William A. Law)
Date: 1995/07/19
Raw View
In article <3uh6mu$qar@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM wrote:

> The only other C library function which takes a callback is bsearch, and
> the draft has similar wording about C linkage for that function.

I would think things like atexit and signal would qualify, as well.

> Such language linkage is an issue only for the C library, since C++
> library functions are expected to have and use C++ linkage.

Perhaps, but isn't qsort a C++ library function?  The language surrounding
the absorption of the standard C library into C++ is a little fuzzy,
though.  It would seem there's room in the standard to make this point
explicitly, in any case.

To look at this differently (more from the poor programmer's perspective,
rather than the language lawyer's or library implementor's), I think a
reasonable objective is to permit existing qsort comparison functions to
be able to be reused with C++ code (e.g., the STL sort algorithm).
Further, it would be nice if I could invoke qsort with either a C++ or a C
comparison function.  Currently, if I forget to preface my function with
'extern "C"' my program would just have undefined behavior(?).  Lastly, it
would be nice to be able to write my own C++ functions/algorithms that can
work with C as well as C++ functions.  For example, I might like to write
C++ code that handles pointers to Windows window procedures (which have C
linkage) or pointers to functions to be dispatched on a thread (which must
have C linkage on most platforms).

Making the linkage-specification part of the type of functions and of
pointers-to-functions makes all that possible, and it is easy to implement
(or so it seems to me).  The only hard part is writing the standard to say
as much.





Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/20
Raw View
In article <bill_law-1907951305110001@bill-law.taligent.com>
bill_law@taligent.com (William A. Law) writes:

[snip]

> To look at this differently (more from the poor programmer's
perspective,
> rather than the language lawyer's or library implementor's), I think a
> reasonable objective is to permit existing qsort comparison functions to
> be able to be reused with C++ code (e.g., the STL sort algorithm).
> Further, it would be nice if I could invoke qsort with either a C++ or a
C
> comparison function.  Currently, if I forget to preface my function with
> 'extern "C"' my program would just have undefined behavior(?).  Lastly,
it
> would be nice to be able to write my own C++ functions/algorithms that
can
> work with C as well as C++ functions.  For example, I might like to
write
> C++ code that handles pointers to Windows window procedures (which have
C
> linkage) or pointers to functions to be dispatched on a thread (which
must
> have C linkage on most platforms).
>
> Making the linkage-specification part of the type of functions and of
> pointers-to-functions makes all that possible, and it is easy to
implement
> (or so it seems to me).  The only hard part is writing the standard to
say
> as much.

I know it's late, but with hindsight, allowing a C++ compiler to use
different calling conventions from the underlying C compiler was probably
a mistake. Sure, it may save us a few CPU cycles here and there, but to
me, the price (an even more complicated pointer to function syntax) is
simply too high. The language is hard enough to understand without it.

- Wil





Author: bill_law@taligent.com (William A. Law)
Date: 1995/07/17
Raw View
In article <3u75rq$snk@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve
Clamage) wrote:

> According to the draft standard, you must use a function with "C"
> linkage.

Could you point to the portion of the draft standard that specifies this,
please?

> > The C++ committee has considered making linkage part of the function
> and function pointer type, but so far has decided not to do so.

The implication then is that the proscription mentioned above is not
inherent in the declaration of qsort but instead is provided in some
normative, function-specific description of the semantics of that
function. How do I then determine what linkage-specification requirements
to document for the pointer-to-function arguments for *my* functions?
I.e., since the linkage-specification isn't part of the "type," how do I
know what linkage convention the compiler will use?

Bill Law





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/17
Raw View
In article 1707951052060001@bill-law.taligent.com, bill_law@taligent.com (William A. Law) writes:
>In article <3u75rq$snk@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve
>Clamage) wrote:
>
>> According to the draft standard, you must use a function with "C"
>> linkage.
>
>Could you point to the portion of the draft standard that specifies this,
>please?

Section 25.4:

" void qsort(void* base, size_t nmemb, size_t size,
 int (*compar)(const void*, const void*));

the function argument compar shall have extern "C" linkage (7.5).  Also, since
compar() may throw an exception, qsort() is allowed to propagate the exception
(17.3.4.8). "

In the April draft, this normative text appears in a Note, but I expect that
to be corrected by removing the "Note" brackets. The term "Note" is used
inconsistently in the April draft, and should be corrected in the next
version. A Note is supposed to contain only non-normative text.

>> > The C++ committee has considered making linkage part of the function
>> and function pointer type, but so far has decided not to do so.
>
> How do I then determine what linkage-specification requirements
>to document for the pointer-to-function arguments for *my* functions?
>I.e., since the linkage-specification isn't part of the "type," how do I
>know what linkage convention the compiler will use?

An excellent question. This is on the list of unresolved issues to be
settled at the next C++ Committee meeting (in November). A suggestion
is to handle language linkage similarly to a throw specification: it
isn't part of the function type, but you can specify it on a pointer
declaration. The exact syntax and semantics haven't been worked out,
but we might wind up with something like this:

 extern "C" int c_func();
 int (*fp1)() = c_func; // error: c_func doesn't have C++ linkage
 extern "C" int (*fp2)() = c_func; // ok

In the last line, the 'extern "C"' would specify the linkage of functions
that fp2 can point to. I don't know how function parameters like "compar"
would be specified.
---
Steve Clamage, stephen.clamage@eng.sun.com







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/17
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
:
: >    When you include the <cstdlib> header within your program, the
: >    qsort() function is declared.  What is the linkage of the function
: >    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
:
: According to the draft standard, you must use a function with "C"
: linkage.

So now that you've answered the preliminary question, answer the rest that
I asked, rather than simply ignoring them.

They were (simply put) how a a conforming implementation can declare such
a function (answer: it cannot in C++ because of the rules govering linkage
specifications) and therefore how many existing implementations that *do*
use `extern "C"' linkage specifications to declare qsort() in their headers
(and I can see at least six from where I'm sitting right now) are about to
break if they implement linkage specifications precisely as specified.





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/17
Raw View
greghunt@zeta.org.au wrote:
: In <3tuqce$7c4@silver.jba.co.uk>, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
: >Quick question for you all :
: >
: >    When you include the <cstdlib> header within your program, the
: >    qsort() function is declared.  What is the linkage of the function
: >    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
:
: I think that the use of the term linkage is a bit problematic...

That's true as well, since strictly speaking "linkage" is a concept
introduced in [basic.link] as simply dealing with the ability to declare
the same object in multiple translation units.

Whereas "linkage specifications" plainly must deal with a lot more.

However, you missed the main point, which was that the qsort function (and
Steve Clamage has now pointed out that in a hidden footnote to chapter 25
-- and we've all managed to wade through to chapter 25 in the few short
weeks since the public comment period started, haven't we ? -- the linkage
of the function pointed to *is* specified as "C", which is as I suspected
it would be) is impossible to declare in the C++ language, since it is
impossible to declare the linkage of a function being pointed to by
a function pointer.

Therefore all of the implementations that *now* use `extern "C"' to declare
qsort are about to break if they stick strictly to the standard since they
will be declaring a different function (one that takes a pointer to a
function with "C++" linkage).

Which in turn means that they'll have to use a magic declaration of qsort
in order to be conformant.

Which in turn means that if they are combined C/C++ implementations (and
how many aren't ?) they are either required to bring in the same magic
declaration to their implementation of the C language, or required to have
all sorts of shenanighans to deal with making #include <stdlib.h> do one
extra-linguistic thing for one language and another thing for the other.





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/17
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
:
: >    When you include the <cstdlib> header within your program, the
: >    qsort() function is declared.  What is the linkage of the function
: >    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
:
: According to the draft standard, you must use a function with "C"
: linkage.

AHEM!  Just for the record ...

According to the draft standard, bits enclosed in "[Note:"..."]" such as
the note right at the bottom of Chapter 25 that you are referring to are
*not* part of the International Standard.

Even if it were, the proper place for it is in [lib.using.linkage].

It should also be noted that it seems a little farcical to expect the
general public to be able to find that reference, and more than a little
silly to expect them to have even managed to get that far through the draft
standard (Chapter *twenty* *five* ??!!) in the short time alloted for the
ANSI public review period (especially as the bulk of the Standard Template
Library precedes it).

Old Pussy and his fellow conspiracy theorists would have a field day going
on about this, you know ...





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/17
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
:                        This is on the list of unresolved issues to be
: settled at the next C++ Committee meeting (in November). A suggestion
: is to handle language linkage similarly to a throw specification: it
: isn't part of the function type, but you can specify it on a pointer
: declaration. The exact syntax and semantics haven't been worked out,
: but we might wind up with something like this:
:
:  extern "C" int c_func();
:  int (*fp1)() = c_func; // error: c_func doesn't have C++ linkage
:  extern "C" int (*fp2)() = c_func; // ok
:
: In the last line, the 'extern "C"' would specify the linkage of functions
: that fp2 can point to. I don't know how function parameters like "compar"
: would be specified.

Look to existing practice.  Implementations that have had to deal with
"linkage specification" issues don't use `extern "C"' because it is
syntactically too cumbersome.  They use constructs such as :

    __declspec(thread) int count ;

or

    void
    _CC(CALLEE_POPS_ARGS|REVERSE_PARMS)
    __declspec(dllexport)
    myfunc ( int, char, char ) ;

or

    void _System emit ( EmitC * cls ) ;

Now if the Standard were to have an "officially blessed" means of including
linkage, calling convention, return convention, name export, distance, and
other such information (albeit with an implementation-defined meaning) then
people who currently have to write

    #if defined(__MYCOMPILER__)
    # define _Export __declspec(dllexport)
    # define _System
    #elif defined(__YOURCOMPILER__)
    # define _Export __export
    # define _System __syscall
    #elif defined(__HISCOMPILER__)
    ..
    ..
    ..

would be a lot happier.

Incidentally, I'd argue against the last line of your example being given a
new meaning.  It already has an existing meaning, that of defining the
linkage specification for the `fp2' object.  Before you complain, there are
at least two major-name C++ implementations that apply linkage specifications
to all "linkable" objects, function or otherwise.





Author: neeri@iis.ee.ethz.ch (Matthias Neeracher)
Date: 1995/07/18
Raw View
Thanks for your explanations so far, Steve!

In article <3uej90$8t7@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) writes:
>>> > The C++ committee has considered making linkage part of the function
>>> and function pointer type, but so far has decided not to do so.
>>
>> How do I then determine what linkage-specification requirements
>> to document for the pointer-to-function arguments for *my* functions?
>> I.e., since the linkage-specification isn't part of the "type," how do I
>> know what linkage convention the compiler will use?

> An excellent question. This is on the list of unresolved issues to be
> settled at the next C++ Committee meeting (in November). A suggestion
> is to handle language linkage similarly to a throw specification: it
> isn't part of the function type, but you can specify it on a pointer
> declaration. The exact syntax and semantics haven't been worked out,
> but we might wind up with something like this:

>  extern "C" int c_func();
>  int (*fp1)() = c_func; // error: c_func doesn't have C++ linkage
>  extern "C" int (*fp2)() = c_func; // ok

> In the last line, the 'extern "C"' would specify the linkage of functions
> that fp2 can point to. I don't know how function parameters like "compar"
> would be specified.

How about a different syntax:

int (extern "C" * fp2)() = c_func;

Having "extern" in the middle of a declaration might look somewhat ugly, but
this solution

 - Works for function parameters, too.
 - Follows from the current C/C++ rules for parameter declaration
   "fp2 is a pointer to a function with "C" linkage"

Matthias

-----
Matthias Neeracher <neeri@iis.ee.ethz.ch> http://err.ethz.ch/members/neeri.html
  "And that's why I am going to turn this world upside down, and make
   of it a fire so *bright* that someone real will notice"
                                -- Vernor Vinge, _Tatja Grimm's World_








Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/18
Raw View
In article 8ja@silver.jba.co.uk, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>Steve Clamage (clamage@Eng.Sun.COM) wrote:
>:                        This is on the list of unresolved issues to be
>: settled at the next C++ Committee meeting (in November). A suggestion
>: is to handle language linkage similarly to a throw specification: it
>: isn't part of the function type, but you can specify it on a pointer
>: declaration. The exact syntax and semantics haven't been worked out,
>: but we might wind up with something like this:
>:
>:  extern "C" int c_func();
>:  int (*fp1)() = c_func; // error: c_func doesn't have C++ linkage
>:  extern "C" int (*fp2)() = c_func; // ok
>:
>: In the last line, the 'extern "C"' would specify the linkage of functions
>: that fp2 can point to. I don't know how function parameters like "compar"
>: would be specified.
>
>Look to existing practice.  Implementations that have had to deal with
>"linkage specification" issues don't use `extern "C"' because it is
>syntactically too cumbersome.  They use constructs such as :

[ examples deleted ]

Since this subject is still under discussion, and the ANSI public comment
period is still open (for one more week), why don't you send in a proposal?

>Incidentally, I'd argue against the last line of your example being given a
>new meaning.  It already has an existing meaning, that of defining the
>linkage specification for the `fp2' object.

In the commentary on page 118 in the ARM, it says that the linkage specifier
applies also to the function pointed to, and gives an example similar to mine.
So the suggestion I mentioned above (not my suggestion, but one being
considered) isn't new. But as I said, the subject is still open.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/15
Raw View
JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:


>    When you include the <cstdlib> header within your program, the
>    qsort() function is declared.  What is the linkage of the function
>    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?

According to the draft standard, you must use a function with "C"
linkage. If on your system there is no difference in linkage (other
than name mangling), the code would also work with a "compare"
function having C++ linkage. This is the case on many, probably
most, systems. The standard does not require that the linakge
be the same, however.

The C++ committee has considered making linkage part of the function
and function pointer type, but so far has decided not to do so.
--
Steve Clamage, stephen.clamage@eng.sun.com





Author: greghunt@zeta.org.au
Date: 1995/07/14
Raw View
In <3tuqce$7c4@silver.jba.co.uk>, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>Quick question for you all :
>
>    When you include the <cstdlib> header within your program, the
>    qsort() function is declared.  What is the linkage of the function
>    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
>

I think that the use of the term linkage is a bit problematic...

The linkage referred to by the standard is linkage editor type
linkage - what the function name gets mashed to in the generated
object code.  It isn't the sequence of instructions that are executed
as part of the routine prolog and epilog.  It is possible for
a routine with one the same prolog and epilog instruction sequence to
have different linkage editor linkage (different name mangling) in
different instances and for it to be callable through a pointer regardless
of the naming.

Greg Hunt





Author: rad6938@gemini.tntech.edu (Rad)
Date: 1995/07/14
Raw View
In article <3tuqce$7c4@silver.jba.co.uk>, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
>Quick question for you all :
>
>    When you include the <cstdlib> header within your program, the
>    qsort() function is declared.  What is the linkage of the function
>    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?
>
>Hint :
>
>    The easy assumption (that the function has "C" linkage) imposes some
>    peculiar constraints upon an implementation, because according to verse
>    6 of Clause 7.5
>
> "... there is no way to specify that the function to which a
> function pointer refers is written in another language."
>
>    Any combined C/C++ implementation therefore *cannot* use the declaration
>
> extern "C" {
>     void qsort(void *, size_t, size_t,
>   int (*compare)(const void *, const void *));
> }
>
>    if it wishes to implement *one* set of functions for both the Standard
>    C Library and the Standard C++ Library, because in C++ the linkage of
>    the function pointed to by `compare' is "C++" linkage, whereas in C
>    the linkage will be "C" linkage.

I don't think this is the case if the C and C++ linkage functions both use
the same method of storing parameters.  In such cases, the only difference
between the two linkages should be the name mangling which is irrelavent from
the point of view of qsort's function pointer.  Therefor I see no reason for no
combined C/C++ implementation being able to use the above declaration.  Only
those implementations which change the methods of passing parameters between
C/C++ linkage are subject to the above problem.  (I wonder if such an
implementation would be conformant anyway?)

----------------------------------------------------------------------------
 Richard Deken                   Graduate student in electrical engineering
 PGP public key available      Tennessee Technological University
 Internet: rad6938@gemini.tntech.edu        Cookeville, TN, USA





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/11
Raw View
Quick question for you all :

    When you include the <cstdlib> header within your program, the
    qsort() function is declared.  What is the linkage of the function
    that you must pass as a pointer ?  Is it "C" or "C++" linkage ?

Hint :

    The easy assumption (that the function has "C" linkage) imposes some
    peculiar constraints upon an implementation, because according to verse
    6 of Clause 7.5

 "... there is no way to specify that the function to which a
 function pointer refers is written in another language."

    Any combined C/C++ implementation therefore *cannot* use the declaration

 extern "C" {
     void qsort(void *, size_t, size_t,
   int (*compare)(const void *, const void *));
 }

    if it wishes to implement *one* set of functions for both the Standard
    C Library and the Standard C++ Library, because in C++ the linkage of
    the function pointed to by `compare' is "C++" linkage, whereas in C
    the linkage will be "C" linkage.

Supplementary questions :

    Is any implementation that uses one set of functions for both the
    Standard C Library and the (equivalent portions of the) Standard C++
    Library non-conforming if it does not declare qsort using a "magic
    declaration", since it is impossible to declare the C qsort function
    in C++ ?

    How many existing implementations currently use one Standard library
    for both the C and C++ languages and use (#ifdef __cpluspls) extern "C"
    around the qsort function declaration in <stdlib.h> ?

    How many implementations are about to break do you think ?