469,267 Members | 972 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,267 developers. It's quick & easy.

extern "C" linker error ---- please explain

Our C++ program was linked with some legacy C functions. We had used
the extern "C" declaration, and everything was working fine. Then
someone thought that it would be better to have a consistent file
naming convention and renamed the files with the legacy C functions
from .c to .cxx. Lo and behold we started getting linker errors left
and right. When we reverted back to the old naming convention, the
problem went away. Also, the problem did not manifest when we kept the
..cxx name and replaced extern "C" with simply extern.

Any help explaining this phenomenon will be appreciated.

Thanks,
Gus

Jul 23 '05 #1
8 1960
Generic Usenet Account wrote:
Our C++ program was linked with some legacy C functions. We had used
the extern "C" declaration, and everything was working fine. Then
someone thought that it would be better to have a consistent file
naming convention and renamed the files with the legacy C functions
from .c to .cxx. Lo and behold we started getting linker errors left
and right. When we reverted back to the old naming convention, the
problem went away. Also, the problem did not manifest when we kept the
.cxx name and replaced extern "C" with simply extern.

Any help explaining this phenomenon will be appreciated.


It could be that your function definitions did not have 'extern "C" ' in
them. IOW, you _declared_ the functions as if they were "C", and then
defined them (in your .cxx files) as "C++". Those translation units that
included the headers needed the functions with the "C" linkage, and there
were none (since the function definitions were "C++").

IOW, you were supposed to have both:
---------------------------------------------- foo.h
extern "C" {
int foo();
double bar();
}
---------------------------------------------- foo.cxx
extern "C" {

int foo()
{
return 42;
}

double bar()
{
return 3.14;
}

} /* extern "C" */
-----------------------------------------------------

V
Jul 23 '05 #2
Generic Usenet Account wrote:
Our C++ program was linked with some legacy C functions. We had used
the extern "C" declaration, and everything was working fine. Then
someone thought that it would be better to have a consistent file
naming convention and renamed the files with the legacy C functions
from .c to .cxx. Lo and behold we started getting linker errors left
and right. When we reverted back to the old naming convention, the
problem went away. Also, the problem did not manifest when we kept the
.cxx name and replaced extern "C" with simply extern.

Any help explaining this phenomenon will be appreciated.

Thanks,
Gus


What compiler are you using?
Some compilers use the filename extension to determine
whether to compile the code as C or C++. The 'cxx'
filename extension is usually interpreted as C++ code.

If you use a 'make' program to build your system, then
either the rules in your Makefile or the DEFAULT rules
built in to the 'make' program that you are using may
be forcing files with a 'cxx' extension to be compiled
as C++ code (even when they contain C code).

In general, C files should have a '.c' filename extension.
Otherwise some compilers and 'make' programs can get very
confused.

Regards,
Larry
Jul 23 '05 #3
Larry I Smith wrote:
What compiler are you using?

gcc version 3.3.1

Jul 23 '05 #4
Generic Usenet Account wrote:
Our C++ program was linked with some legacy C functions. We had used
the extern "C" declaration, and everything was working fine. Then
someone thought that it would be better to have a consistent file
naming convention and renamed the files with the legacy C functions
from .c to .cxx. Lo and behold we started getting linker errors left
and right. When we reverted back to the old naming convention, the
problem went away. Also, the problem did not manifest when we kept the
.cxx name and replaced extern "C" with simply extern.


Your compiler probably assumes that extensions like .cxx, .cpp, etc. are
C++ and compiles them as C++ instead of C.

--
Mike Smith
Jul 23 '05 #5
Victor Bazarov wrote:
Larry I Smith wrote:
[...] For one thing the args to function calls are
pushed on to the stack in different order in C vs C++.


REALLY?!
[..].


My info may be out of date, but C pushes the args
in left-to-right order (allowing support for a variable
number of args), and C++ uses the Pascal-style
of right-to-left order. The order of the args on the
stack is (was in the 80's) standardized to allow libs
from multiple vendors to inter-operate.

As I recall, in C the calling code cleans up the call stack
after a function call returns, but in C++ the called
function cleans up the call stack before returning.

Regards,
Larry
Jul 23 '05 #6
Larry I Smith wrote:
Victor Bazarov wrote:
Larry I Smith wrote:
[...] For one thing the args to function calls are
pushed on to the stack in different order in C vs C++.
REALLY?!

[..].

My info may be out of date, but C pushes the args
in left-to-right order (allowing support for a variable
number of args), and C++ uses the Pascal-style
of right-to-left order.


So, this suggests that C++ has no support for a variable number of rags.
Is that so?
The order of the args on the
stack is (was in the 80's) standardized to allow libs
from multiple vendors to inter-operate.

As I recall, in C the calling code cleans up the call stack
after a function call returns, but in C++ the called
function cleans up the call stack before returning.


I think you've confused C++ with Pascal.

V
Jul 23 '05 #7
Larry I Smith wrote:
Victor Bazarov wrote:
Larry I Smith wrote:
[...] For one thing the args to function calls are
pushed on to the stack in different order in C vs C++.

REALLY?!
[..].


My info may be out of date, but C pushes the args
in left-to-right order (allowing support for a variable
number of args), and C++ uses the Pascal-style
of right-to-left order. The order of the args on the
stack is (was in the 80's) standardized to allow libs
from multiple vendors to inter-operate.

As I recall, in C the calling code cleans up the call stack
after a function call returns, but in C++ the called
function cleans up the call stack before returning.

Regards,
Larry


Oops, the stack order pushes I mention above are reversed.

In C the caller cleans up the stack because a variable
number of args may have been pushed, and the called function
may not know how much stack to pop.

It's tough getting old - the memory goes first...

Larry
Jul 23 '05 #8
Victor Bazarov wrote:
Larry I Smith wrote:
Victor Bazarov wrote:
Larry I Smith wrote:

[...] For one thing the args to function calls are
pushed on to the stack in different order in C vs C++.

REALLY?!
[..].

My info may be out of date, but C pushes the args
in left-to-right order (allowing support for a variable
number of args), and C++ uses the Pascal-style
of right-to-left order.


So, this suggests that C++ has no support for a variable number of rags.
Is that so?
The order of the args on the
stack is (was in the 80's) standardized to allow libs
from multiple vendors to inter-operate.

As I recall, in C the calling code cleans up the call stack
after a function call returns, but in C++ the called
function cleans up the call stack before returning.


I think you've confused C++ with Pascal.

V


A long time ago in a galaxy far, far away, my job was to write
asm code to interface with both C and C++.

Page 3 in the following doc provides a brief summary of the
call stack procedures:

http://www.nuvisionmiami.com/books/a...s/CppCalls.pdf

The example asm module discussed uses the C calling convention
(push args in reverse order, caller cleans up the stack after
the called function returns). Note that the functions discussed
are all declared 'extern "C"' in the C++ code to advise the
compiler that these functions use the C call stack layout
rather than the C++ call stack layout.

Following is another doc describing the differences between the
C and C++ call stack layouts. Although this doc is MS VC specific,
variations of the '__cdecl' and 'thiscall' stack layouts are
used on most OS'es. The '__cdecl' style stack is used for C
functions and C++ functions with variable arg list, and the
'thiscall' style stack is used for C++ functions that do not
have a variable arg list.

http://www.codeproject.com/cpp/calli...emystified.asp

Regards,
Larry
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.