default argument and shared library

S

S S

Hi

Here is the situation,

I have one line "a.h" as below
extern "C" void afun(int a)

I have "a.cc" as below
#include<iostream>
using namespace std;
extern "C" void afun(int a)
{
cout << "A= " << a;
}

I have "main.cc" as below
#include<iostream>
#include "a.h"
using namespace std;
int main()
{
afun(10);
return 0;
}

Now I compile the a.cc file and create a shared library a.so
g++ -shared -fPIC a.cc -o a.so

Now I compile main.cc using a.h and a.so and create executable a.out
g++ -g a.h main.cc a.so

When I run executable 'a.out', I get output as below
A= 10
which is of course correct.

Now I modify a.h and a.cc with one extra argument as below,
a.h
===
extern "C" void afun(int a, int b = 1);

a.cc
===
#include<iostream>
using namespace std;
extern "C" void afun(int a, int b)
{
cout << "A= " << a << "B= " <<b;
}

Now I again update my a.so with below command
g++ -shared -fPIC a.cc -o a.so

But I do not want to update my a.out, I want new shared file to be
used with old executable 'a.out' and that is the sole purpose of
adding default argument (otherwise non default argument could also be
the choice).

But when I run a.out, I get
A= 10 B= -18776767
which is ofcourse garbage value.

Why default argument is not reflected in shared file and the
executable?
And yes, new argument is surely reflected as seen from output !

Thanks
 
F

Fred Zwarts

S S said:
Hi

Here is the situation,

I have one line "a.h" as below
extern "C" void afun(int a)

I have "a.cc" as below
#include<iostream>
using namespace std;
extern "C" void afun(int a)
{
cout << "A= " << a;
}

I have "main.cc" as below
#include<iostream>
#include "a.h"
using namespace std;
int main()
{
afun(10);
return 0;
}

Now I compile the a.cc file and create a shared library a.so
g++ -shared -fPIC a.cc -o a.so

Now I compile main.cc using a.h and a.so and create executable a.out
g++ -g a.h main.cc a.so

When I run executable 'a.out', I get output as below
A= 10
which is of course correct.

Now I modify a.h and a.cc with one extra argument as below,
a.h
===
extern "C" void afun(int a, int b = 1);

a.cc
===
#include<iostream>
using namespace std;
extern "C" void afun(int a, int b)
{
cout << "A= " << a << "B= " <<b;
}

Now I again update my a.so with below command
g++ -shared -fPIC a.cc -o a.so

But I do not want to update my a.out, I want new shared file to be
used with old executable 'a.out' and that is the sole purpose of
adding default argument (otherwise non default argument could also be
the choice).

But when I run a.out, I get
A= 10 B= -18776767
which is ofcourse garbage value.

Why default argument is not reflected in shared file and the
executable?
And yes, new argument is surely reflected as seen from output !

Thanks

The use of shared libraries is not defined in the C++ standard.
This is a operating system dependent question, which is not in the scope of this newsgroup.
In other newsgroups you might get better answers.
I don't see a reason why the compiler could not put the default value in the main executable.
After all, the a.h file is included in main.cc.
But the question why it is implemented like this, I cannot answer, except that I guess that it
is easier to implement.
 
J

James Kanze

Here is the situation,
I have one line "a.h" as below
extern "C" void afun(int a)
I have "a.cc" as below
#include<iostream>
using namespace std;
extern "C" void afun(int a)
{
cout << "A= " << a;
}
I have "main.cc" as below
#include<iostream>
#include "a.h"
using namespace std;
int main()
{
afun(10);
return 0;
}
Now I compile the a.cc file and create a shared library a.so
g++ -shared -fPIC a.cc -o a.so
Now I compile main.cc using a.h and a.so and create executable a.out
g++ -g a.h main.cc a.so
When I run executable 'a.out', I get output as below
A= 10
which is of course correct.
Now I modify a.h and a.cc with one extra argument as below,
a.h
===
extern "C" void afun(int a, int b = 1);
a.cc
===
#include<iostream>
using namespace std;
extern "C" void afun(int a, int b)
{
cout << "A= " << a << "B= " <<b;
}
Now I again update my a.so with below command
g++ -shared -fPIC a.cc -o a.so
But I do not want to update my a.out, I want new shared file
to be used with old executable 'a.out' and that is the sole
purpose of adding default argument (otherwise non default
argument could also be the choice).

You can't. You've changed the interface. If the function
wasn't ``extern "C"'', you could use overloading, but as it is,
the only solution is to introduce a new function, with a
different name, which takes two arguments.
But when I run a.out, I get
A= 10 B= -18776767
which is ofcourse garbage value.
Why default argument is not reflected in shared file and the
executable?

Because the default argument is only used at the call site. A
function
void afun( int a, int b = 1 ) ;
, is a function which takes two arguments, both of which have
type int. The ``= 1'' only comes into play at the call site,
telling the compiler what to pass if you don't provide a value.

If your function hadn't been ``extern "C"'', you'd probably have
gotten an error from the dynamic link, saying it couldn't find
the function.
 
I

Ismo Salonen

--snip--

(Hopefully this is not your homework assignment)

because the default arguments are evaluated at calling time by compiler.
You did not recompile the executable thus the calling program did not
pass the default value as an argument.

What you are trying to do is never going to work.

This executed only because you were using extern "C" which does not
decorate the function names. In real C++ this would not run as the new
afun() signature (int,int) does not match the caller (int).

ismo
 
J

James Kanze


[...]
The use of shared libraries is not defined in the C++ standard.
So?

This is a operating system dependent question, which is not in
the scope of this newsgroup.

Not really. The answer to his question will be pretty much the
same, regardless of the OS.

Formally speaking, limiting oneself to the standard, his code
has undefined behavior, because it contains a violation of the
one definition rule. This has nothing to do with dynamic
linking; he has compiled part of the program with one
declaration of the function, and part with a different
declaration.
In other newsgroups you might get better answers. I don't see
a reason why the compiler could not put the default value in
the main executable. After all, the a.h file is included in
main.cc. But the question why it is implemented like this, I
cannot answer, except that I guess that it is easier to
implement.

Actually, if you read the standard closely, you'll realize that
about the only plausible implementation evaluates the default
argument at the call site.
 
S

Sarvesh Singh


    [...]
The use of shared libraries is not defined in the C++ standard.
So?

This is a operating system dependent question, which is not in
the scope of this newsgroup.

Not really.  The answer to his question will be pretty much the
same, regardless of the OS.

Formally speaking, limiting oneself to the standard, his code
has undefined behavior, because it contains a violation of the
one definition rule.  This has nothing to do with dynamic
linking; he has compiled part of the program with one
declaration of the function, and part with a different
declaration.
In other newsgroups you might get better answers.  I don't see
a reason why the compiler could not put the default value in
the main executable.  After all, the a.h file is included in
main.cc.  But the question why it is implemented like this, I
cannot answer, except that I guess that it is easier to
implement.

Actually, if you read the standard closely, you'll realize that
about the only plausible implementation evaluates the default
argument at the call site.

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

This is real nightmare for industry where we need to write different
version of function everytime we add new argument. I can not remove
extern C because then user may not find the function name if he is
using C compiler. So extern C helps for both compilers compatibility.

Preserving old functions solves the purpose to support backward
compatiblity. Some executables might want to use new shared library
with old executable version. Hence single library for all executable
version support is the problem. Don't know how to imitate this default
argument thing, currently I am adding new functions to this. Any
suggestions?

Thanks
 
I

Ismo Salonen

Sarvesh said:
messagenews:[email protected]... [...]

The use of shared libraries is not defined in the C++ standard. So?

This is a operating system dependent question, which is not in
the scope of this newsgroup.
Not really. The answer to his question will be pretty much the
same, regardless of the OS.

Formally speaking, limiting oneself to the standard, his code
has undefined behavior, because it contains a violation of the
one definition rule. This has nothing to do with dynamic
linking; he has compiled part of the program with one
declaration of the function, and part with a different
declaration.
In other newsgroups you might get better answers. I don't see
a reason why the compiler could not put the default value in
the main executable. After all, the a.h file is included in
main.cc. But the question why it is implemented like this, I
cannot answer, except that I guess that it is easier to
implement.
Actually, if you read the standard closely, you'll realize that
about the only plausible implementation evaluates the default
argument at the call site.

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

This is real nightmare for industry where we need to write different
version of function everytime we add new argument. I can not remove
extern C because then user may not find the function name if he is
using C compiler. So extern C helps for both compilers compatibility.

Preserving old functions solves the purpose to support backward
compatiblity. Some executables might want to use new shared library
with old executable version. Hence single library for all executable
version support is the problem. Don't know how to imitate this default
argument thing, currently I am adding new functions to this. Any
suggestions?

Thanks

Add version number to the function name is the only plausible solution
for your case. The caller places the arguments to
registers/stack/whatever place and uses the prototype for this.

How do you expect the old executable change when you change the source
code ?

You must revert to interpreted language if you really need this of then
you must invent a way to tell callee the argument description.

Something like printf-family format. And varargs.

The industry has worked with this constraint over 20 years, C++
introduced default arguments, old C did not have those, dunno about
current standard.

ismo
 
J

James Kanze

[...]
The use of shared libraries is not defined in the C++ standard.
So?
This is a operating system dependent question, which is
not in the scope of this newsgroup.
Not really. The answer to his question will be pretty much
the same, regardless of the OS.
Formally speaking, limiting oneself to the standard, his
code has undefined behavior, because it contains a violation
of the one definition rule. This has nothing to do with
dynamic linking; he has compiled part of the program with
one declaration of the function, and part with a different
declaration.
In other newsgroups you might get better answers. I don't
see a reason why the compiler could not put the default
value in the main executable. After all, the a.h file is
included in main.cc. But the question why it is
implemented like this, I cannot answer, except that I
guess that it is easier to implement.
Actually, if you read the standard closely, you'll realize
that about the only plausible implementation evaluates the
default argument at the call site.
This is real nightmare for industry where we need to write
different version of function everytime we add new argument. I
can not remove extern C because then user may not find the
function name if he is using C compiler. So extern C helps for
both compilers compatibility.

The "nightmare" would be to allow an existing function to change
its signature. In C++, there's no real problem---you use
namespaces for versioning, and you can usually add non-member
functions to the interface without the need to create a new
version. (Although this may also lead to confusion if
overloading is involved.) If you use ``extern "C"'', on the
other hand, you're locked into the rules which hold for C, which
means no function overloading, and no versionning.
Preserving old functions solves the purpose to support
backward compatiblity. Some executables might want to use new
shared library with old executable version. Hence single
library for all executable version support is the problem.
Don't know how to imitate this default argument thing,
currently I am adding new functions to this. Any suggestions?

Forget about ``extern "C"''. Use namespaces for versionning.
 
S

Sarvesh Singh

message    [...]
The use of shared libraries is not defined in the C++ standard.
So?
This is a operating system dependent question, which is
not in the scope of this newsgroup.
Not really.  The answer to his question will be pretty much
the same, regardless of the OS.
Formally speaking, limiting oneself to the standard, his
code has undefined behavior, because it contains a violation
of the one definition rule.  This has nothing to do with
dynamic linking; he has compiled part of the program with
one declaration of the function, and part with a different
declaration.
In other newsgroups you might get better answers.  I don't
see a reason why the compiler could not put the default
value in the main executable.  After all, the a.h file is
included in main.cc.  But the question why it is
implemented like this, I cannot answer, except that I
guess that it is easier to implement.
Actually, if you read the standard closely, you'll realize
that about the only plausible implementation evaluates the
default argument at the call site.
This is real nightmare for industry where we need to write
different version of function everytime we add new argument. I
can not remove extern C because then user may not find the
function name if he is using C compiler. So extern C helps for
both compilers compatibility.

The "nightmare" would be to allow an existing function to change
its signature.  In C++, there's no real problem---you use
namespaces for versioning, and you can usually add non-member
functions to the interface without the need to create a new
version.  (Although this may also lead to confusion if
overloading is involved.)  If you use ``extern "C"'', on the
other hand, you're locked into the rules which hold for C, which
means no function overloading, and no versionning.
Preserving old functions solves the purpose to support
backward compatiblity. Some executables might want to use new
shared library with old executable version. Hence single
library for all executable version support is the problem.
Don't know how to imitate this default argument thing,
currently I am adding new functions to this. Any suggestions?

Forget about ``extern "C"''.  Use namespaces for versionning.

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -

- Show quoted text -

Can you please be more elaborate on namespace versioning giving some
examples or some link?

Thanks a lot
 
J

James Kanze

On Aug 4, 12:53 pm, James Kanze <[email protected]> wrote:
Can you please be more elaborate on namespace versioning
giving some examples or some link?

I've forgotten where I got the idea from---Nathan Myers, I
think. But the principle is simple: everything in the interface
is in a namespace, something like:

namespace MyNameWithVersion {
// ...
}
namespace MyName = MyNameWithVersion ;

You then define MyNameWithVersion to something like
MyName_2009v01.

Client code, of course, just uses namespace MyName. If it
attempts to link with the wrong version (a different version
than the one with which it was compiled), the link fails. It's
also possible to put several versions in a library or a dynamic
object, with each sub-module picking up the version it needs
(supposing that there is no data defined in the library which
needs to be shared between the sub-modules).
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top