JTC1/SC22/WG21
N0722
Accredited Standards Committee X3 Doc No: X3J16/95-0122 WG21/N0722
Information Processing Systems Date: Jun 30, 1995 Page 1 of 4
Operating under the procedures of Project: Programming Language C++
American National Standards Institute Ref Doc: X3J16/94-0034 WG21/N0421
Reply to: Josee Lajoie
(josee@vnet.ibm.com)
extern "C" and the C++ type system (Revision 1)
==================================
This is the second version (almost identical to the first) of a paper
presented to the committee in the Pre San Diego mailing (March 94). This
topic was never discussed by the committee and I believe should be before
we can mark the issue closed.
1. Problem
-------
Is the linkage specified in a linkage-specification part of the
function type?
Because the C portion of the C++ standard library contains functions that take
pointers to functions, the answer to this question cannot be left as
implementation-defined:
17.4.7 Signal Handling
(the same as 7.7 of the ISO C Standard)
void (*signal (int sig, void (*func) (int)) ) (int);
17.4.10.5 Searching and sorting utilities
(the same as 7.10.5 of the ISO C Standard)
void *bsearch (const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar) (const void *, const void *) );
void *qsort (void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *) );
It is important to specify in the C++ standard if these functions take
pointers to functions with C linkage or pointers to functions with C++
linkage. On some systems, C functions and C++ functions may have
different calling conventions and calling a function using a pointer to
function with the "wrong" linkage may result in a failure at runtime.
2. linkage-specifications influence a function type
------------------------------------------------
Proposal 1:
----------
The linkage specified by an extern "C" linkage-specification is part of a
function type.
I can see two ways to do this.
2.1 A linkage-specification affects all function types in a declaration
-------------------------------------------------------------------
The linkage-specification 'extern "C"' affects all the function
types in a declaration. Therefore, the declaration:
extern "C" void (*signal (int sig, void (*func) (int)) ) (int);
gives the function 'signal' the following type:
function with "C" linkage taking
1 parameter of type "int" and
1 parameter of type "pointer to function with "C" linkage"
and returning a pointer to function with "C" linkage.
2.2 A linkage-specification only affects the type of the declarator
---------------------------------------------------------------
The linkage-specification 'extern "C"' only affects the type of the
declarator. Therefore, the declaration:
extern "C" void (*signal (int sig, void (*func) (int)) ) (int);
gives the function 'signal' the following type:
function with "C" linkage taking
1 parameter of type "int" and
1 parameter of type "pointer to function with "C++" linkage"
and returning a pointer to function with "C++" linkage.
How would one declare 'signal''s second parameter type and return type
to be pointer to functions with "C" linkage? Typedefsi must be used:
extern "C" typedef void handler_type(int);
extern "C" handler_type* signal (int sig, handler_type* func) ;
2.3 Discussion:
----------
I have a slight preference for 2.2 because it is more explicit but
I must say that neither of these solutions comes out as a clear
winner.
Solution 2.1:
------------
This solution serves the C library (and therefore old code) well. I
assume that when users of a C library write:
extern "C" void (*signal (int sig, void (*func) (int)) ) (int);
they want all function types to have C linkage. After all, the
library routine is most certainly written to accept and return a
function with "C" linkage.
This solution however renders it more difficult to declare functions
that have parameters of function type with different linkage type.
For example:
extern "C++" typedef void func_type(int);
extern "C" int f(func_type* parm);
What is the linkage of the function pointed at by 'parm'? "C" or "C++"?
If it is "C++", then why is it that the 'extern "C"'
linkage-specification didn't affect all the function types in the
declaration?
Solution 2.2
------------
As described above, this solution is more flexible. It allows users
to separate the linkage of a function with that of its parameters or
return type. For example, in the declaration of 'f':
extern "C" void f ( int (*pf) (int) );
the linkage-specification applies only to 'f' and not to 'pf'.
However this solution can appear to be more cumbersome since typedefs
are required to declare functions (like 'signal') in the C library.
Another question that has to be answered if solution 2.2 is adopted
is: to what type of declarator can a linkage specification apply?
2.2.1 a function type, obviously
2.2.2 should a pointer to function type be influenced by a
linkage-specification?
For example:
extern "C" int (*pf) (int);
does this declaration declare a pointer to a "C" function, is the
linkage-specification ignored or is the declaration in error?
2.2.3 should other declarator types convey linkage as well?
For example:
extern "C" void (*a[3]) (int);
does this declaration declare an array of pointers to "C" functions
is the linkage-specification ignored or is the declaration in error?
Of all these 3 points, I would definitely allow point 2.2.1, and
definitely disallow point 2.2.3. I am ambivalent regarding point
2.2.2. I would prefer to disallow it and say that a
linkage-specification only applies to a declarator of function type,
but this doesn't accurately reflect current practice. On some
implementations, linkage-specifications influence the type of a
pointer.
Proposal 2:
----------
An extern "C" linkage-specification affects the type of a declarator
introduced by a function declaration or by a typedef declaration declaring
a function type.
[solutions 2.2 and 2.2.1 above]
3. Type Conversions
----------------
Proposal 3:
----------
A C++ function and an extern "C" function have different types.
No implicit conversion exits between pointers to functions with different
linkages. Explicit type conversions (reinterpret_casts?) are allowed between
pointers to functions with different linkages.
This implies that two pointers to functions with different linkages
have different types and cannot be assigned to the one another, cannot
be used to initialize one another, ... .
4. Overloading
-----------
The working paper already says in 7.5 Linkage specifications
"At most one of a set of functions of overloaded functions with a
particular name can have C linkage."
This is sufficient.