avoiding multiple definition error

J

joe.user0

Your C program is using library libA which has a structure
struS.

You need to modify struS but may not touch the library. How
can your program redefine the structure struS while keeping
the compiler happy?
 
I

Ian Collins

Your C program is using library libA which has a structure
struS.

You need to modify struS but may not touch the library. How
can your program redefine the structure struS while keeping
the compiler happy?
It can't.
 
J

jaysome

Your C program is using library libA which has a structure
struS.

You need to modify struS but may not touch the library. How
can your program redefine the structure struS while keeping
the compiler happy?

This could be accomplished if struS is declared with external linkage
and its type is visible to your C program. Something like the
following snippets:

/* libA.h */
struct foo {int bar;}

/* libA.c */
struct foo struS;

/* yourcprogram.c */
extern struct foo struS;
struS.bar = 0;

Note that if struS was defined with internal linkage (like it arguably
should have been):

/* libA.c */
static struct foo struS;

then there is no standard way to modify struS without "touching the
library" (e.g., calling a function that modifies struS).

Regards
 
M

Martin Golding

Your C program is using library libA which has a structure struS.
You need to modify struS but may not touch the library. How can your
program redefine the structure struS while keeping the compiler happy?

Your subject implies a name conflict, that is, you want to name
something struS that's unrelated to libA, but use other features
of libA. In that case, just rename the struct when you include the
header file

#define struS libAstruS
#include <libAheader.h>
#undef struS

If you really mean you want to modify struS to your own taste, the
standard allows you _only_ to add fields to the end _of your own copies_
of struS:

#define struS libAstruS
#include <libAheader.h>
#undef struS

--- then either (A):

struct struS {
... libA fields of struS ...
... your new fields ...
};

--- or (B):

struct struS {
libAstruS libAbits;
... your new fields ...
};

The second form protects you from changes to the library's definition,
and allows you to call properly prototyped functions more cleanly.
With (A), you'll have to cast:

struct struS mystruS;
libAfunc((struct libAstruS *) &mystruS);

with (B), just name the library's part:

struct struS mystruS;
libAfunc(&mystruS.libAbits);


Neither solution is more to my taste than leaving the library name alone
and incorporating the libA struS into a struct of your very own (C):

stuct mystruS {
struS libAstruS libAbits;
... your new fields ...
};

struct mystruS mystruS;
libAfunc(&mystruS.libAbits);


In any of the cases, you'll have to do some fiddling if the library
creates struSes. For example, if the libA header declares a function
struct struS libAnew_struS(void);


(A)
struct struS mystruS;
struct libAstruS *pstruS = (struct libAstruS *) &mystruS;

*pstruS = libAnew_struS();

(B)
struct struS mystruS;
mystruS.libAbits = libAnew_struS();

(C)
struct mystruS mystruS;
mystruS.libAbits = libAnew_struS();



If the library exports global struSes, you're out of luck entirely.
eg, given (B)

extern struS gblstruS;

gblstruS.libAfield = xxx; /* OK */
gblstrus.newfield = xxx; /* abort, if you're very lucky */

In that case, declare your own structs containing pointers to libA struSes.

Martin
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top