I think we are getting at the heart of the disagreement. To me, a
normal C++ 'module' contains such things as functions with modified
names, reflecting the parameters, and used to separate the various
forms.
The thing is, you can tell *every* [%] C++ compiler *not* to use "mangled
names", simply by writing one special C++ declaration in front of
the function definition.
[% See parenthetical caveat below, also marked with [%].]
Imagine, if you will, that we have -- instead of C and C++ -- the
two languages P and L. In P, we write:
linkage "L":
declare foo as function taking integer and returning nothing.
begin function foo:
input parameter x is integer;
write x;
end function foo.
end linkage "L".
declare bar as function taking Lstring and returning nothing.
begin function bar:
input parameter p is Lstring;
write p;
end function bar.
In L, however, we write:
extern func foo [int];
extern (interface "P") func bar [string];
Now a program in language L can call both foo and bar, even though
both are defined in language P. A program in language P can also
(of course) call both foo and bar. Here, both languages have some
sort of special syntax specifically designed to interface with each
other.
If P and L use header files, then -- since the syntax differs --
we must obviously write two *separate* header files for P and L
to declare foo and bar in each. (The indented text above *is*
the L-language header, in fact. The P-language header simly
omits the source code for foo and bar -- the parts from "begin
function" to "end function".)
In the case of C and C++, however, instead of *both* languages
having some sort of special syntax, only C++ has the special syntax.
Luckily, only one such syntax is required -- normally, to turn off
the "name mangling" you know about. ([%] On some systems it might
do more and/or less than just disable name mangling. In particular,
C compilers are *also* allowed to do name mangling; it is just that
most avoid it, both because of tradition/history, and because extra
work is then required to handle old K&R-style non-prototyped
functions. The key item, in any case, is that the C++ special
syntax, required in every C++ compiler, tells that C++ compiler
that the functions so declared should be compiled such that they
use the C++ implementation's C-language linkage conventions, whatever
those are. That allows any later definition of those functions --
in any language, even if they are written in Pascal or Java -- to
call or be called from anything that is capable of using those
C-language linkage conventions.)
Because only the C++ side has the special syntax, you have to prefix
any C++ function *definition* with the appropriate syntax, so that
the C++ compiler does whatever is required to make that C++ function
callable from C.
At the same time, though, because C and C++ share so much syntax,
we can actually write a single "foo.h" header file, using those
annoying "#ifdef __cplusplus" lines, so that our two logically-separate
headers (for-c-foo.h and for-c++-foo.h) occupy a single source
file. We could do the same with the P and L headers, if there is
some sort of shared preprocessor for each, but there is less reason
to do so, since we would end up with:
#ifdef __P_LANGUAGE__
linkage "L":
declare foo as function taking integer and returning nothing.
end linkage "L".
#else
extern func foo [int];
#endif
If C were to adopt the C++ syntax for "extern", we could even
eliminate the annoying #ifdef from the shared C and C++ headers.
Perhaps we could also add name-mangling to C compilers so that we
could write:
extern "C++" somefunc(const char *);
instead of using:
extern "C" somefunc(const char *p) { ... }
on the C++ side -- but that would just be "completing the symmetry",
not actually adding any new functionality.