Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #70459 > unrolled thread

Irritating multiple redefinition problem -- please help

Started bydakupoto@gmail.com
First post2015-09-13 20:39 -0700
Last post2015-09-20 20:24 +0000
Articles 12 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Irritating multiple redefinition problem -- please help dakupoto@gmail.com - 2015-09-13 20:39 -0700
    Re: Irritating multiple redefinition problem -- please help Ian Collins <ian-news@hotmail.com> - 2015-09-14 15:50 +1200
      Re: Irritating multiple redefinition problem -- please help David Brown <david.brown@hesbynett.no> - 2015-09-14 10:24 +0200
        Re: Irritating multiple redefinition problem -- please help August Karlstrom <fusionfile@gmail.com> - 2015-09-14 14:39 +0200
          Re: Irritating multiple redefinition problem -- please help David Brown <david.brown@hesbynett.no> - 2015-09-14 15:45 +0200
            Re: Irritating multiple redefinition problem -- please help Richard Heathfield <rjh@cpax.org.uk> - 2015-09-14 14:52 +0100
              Re: Irritating multiple redefinition problem -- please help August Karlstrom <fusionfile@gmail.com> - 2015-09-14 18:13 +0200
            Re: Irritating multiple redefinition problem -- please help Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-14 16:41 +0100
            Re: Irritating multiple redefinition problem -- please help dakupoto@gmail.com - 2015-09-14 19:47 -0700
              Re: Irritating multiple redefinition problem -- please help Paul N <gw7rib@aol.com> - 2015-09-15 16:00 -0700
    Re: Irritating multiple redefinition problem -- please help gordonb.78i5t@burditt.org (Gordon Burditt) - 2015-09-13 23:40 -0500
    Re: Irritating multiple redefinition problem -- please help Ike Naar <ike@iceland.freeshell.org> - 2015-09-20 20:24 +0000

#70459 — Irritating multiple redefinition problem -- please help

Fromdakupoto@gmail.com
Date2015-09-13 20:39 -0700
SubjectIrritating multiple redefinition problem -- please help
Message-ID<d26a19b9-2aa7-451d-9df4-14ece63ad4a2@googlegroups.com>
Could some C guru please help ? I have the 
following set of ".h" and ".c" files.
A.h, B.h, C.h, B.c and C.c. A.h contains
constants as:
const double PI2 = 6.28;
and so on.
A.h is included in B.h.
and B.h is included in 
C.h 
The main executable is C.c
(contains int main(int argc, 
char **argv)) and uses 
utility functions defined 
in B.c 
I compile with the command 
line:
gcc -g -o C.c B.c -lm
I get error messages as :
/tmp/cckNfO8Q.o:(.rodata+0x0): multiple definition of `PI'
/tmp/cc2ggMjE.o:(.rodata+0x0): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x8): multiple definition of `PI2'
/tmp/cc2ggMjE.o:(.rodata+0x8): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x10): multiple definition of `TOL'
/tmp/cc2ggMjE.o:(.rodata+0x10): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x18): multiple definition of `TOLC'
/tmp/cc2ggMjE.o:(.rodata+0x18): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x20): multiple definition of `UCT'
/tmp/cc2ggMjE.o:(.rodata+0x20): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x28): multiple definition of `USW'
/tmp/cc2ggMjE.o:(.rodata+0x28): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x30): multiple definition of `AWGlwn'
/tmp/cc2ggMjE.o:(.rodata+0x30): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x34): multiple definition of `MCOL'
/tmp/cc2ggMjE.o:(.rodata+0x34): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x38): multiple definition of `MCOLC'
/tmp/cc2ggMjE.o:(.rodata+0x38): first defined here
/tmp/cckNfO8Q.o:(.rodata+0x3c): multiple definition of `MCOLRC'
/tmp/cc2ggMjE.o:(.rodata+0x3c): first defined here
/tmp/cckNfO8Q.o:(.data+0x0): multiple definition of `Cores'
/tmp/cc2ggMjE.o:(.data+0x0): first defined here
/tmp/cckNfO8Q.o:(.data+0x1ac0): multiple definition of `AWG'
/tmp/cc2ggMjE.o:(.data+0x1ac0): first defined here
collect2: ld returned 1 exit status

Could some one please 
provide some hints as
to what is going wrong.
Thanks in advance.
  
   

[toc] | [next] | [standalone]


#70460

FromIan Collins <ian-news@hotmail.com>
Date2015-09-14 15:50 +1200
Message-ID<d5mufiF884kU11@mid.individual.net>
In reply to#70459
dakupoto@gmail.com wrote:
> Could some C guru please help ? I have the
> following set of ".h" and ".c" files.
> A.h, B.h, C.h, B.c and C.c. A.h contains
> constants as:
> const double PI2 = 6.28;

I'm sure I've seen this exact question before...

Make the declaration in the header

extern const double PI2;

and define in in one and only one .c file

const double PI2 = 6.28;

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#70465

FromDavid Brown <david.brown@hesbynett.no>
Date2015-09-14 10:24 +0200
Message-ID<mt6046$slc$1@dont-email.me>
In reply to#70460
On 14/09/15 05:50, Ian Collins wrote:
> dakupoto@gmail.com wrote:
>> Could some C guru please help ? I have the
>> following set of ".h" and ".c" files.
>> A.h, B.h, C.h, B.c and C.c. A.h contains
>> constants as:
>> const double PI2 = 6.28;
> 
> I'm sure I've seen this exact question before...
> 
> Make the declaration in the header
> 
> extern const double PI2;
> 
> and define in in one and only one .c file
> 
> const double PI2 = 6.28;
> 

Alternatively, especially for simple constants, change the declaration
in the header file to the definition :

static const double PI2 = 6.28;

and remove any definition in .c files.

(There are differences in these two techniques, but in cases like yours
then either can usually be used.  Using a static const in the header
will often lead to more efficient code, if that is relevant to you.)

[toc] | [prev] | [next] | [standalone]


#70486

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-14 14:39 +0200
Message-ID<mt6f5q$ftr$1@speranza.aioe.org>
In reply to#70465
On 2015-09-14 10:24, David Brown wrote:
> On 14/09/15 05:50, Ian Collins wrote:
>> Make the declaration in the header
>>
>> extern const double PI2;
>>
>> and define in in one and only one .c file
>>
>> const double PI2 = 6.28;
>>
>
> Alternatively, especially for simple constants, change the declaration
> in the header file to the definition :
>
> static const double PI2 = 6.28;
>
> and remove any definition in .c files.
>
> (There are differences in these two techniques, but in cases like yours
> then either can usually be used.  Using a static const in the header
> will often lead to more efficient code, if that is relevant to you.)

Why not simply

	#define PI2 6.28

?


-- August

[toc] | [prev] | [next] | [standalone]


#70497

FromDavid Brown <david.brown@hesbynett.no>
Date2015-09-14 15:45 +0200
Message-ID<mt6ite$1bb$1@dont-email.me>
In reply to#70486
On 14/09/15 14:39, August Karlstrom wrote:
> On 2015-09-14 10:24, David Brown wrote:
>> On 14/09/15 05:50, Ian Collins wrote:
>>> Make the declaration in the header
>>>
>>> extern const double PI2;
>>>
>>> and define in in one and only one .c file
>>>
>>> const double PI2 = 6.28;
>>>
>>
>> Alternatively, especially for simple constants, change the declaration
>> in the header file to the definition :
>>
>> static const double PI2 = 6.28;
>>
>> and remove any definition in .c files.
>>
>> (There are differences in these two techniques, but in cases like yours
>> then either can usually be used.  Using a static const in the header
>> will often lead to more efficient code, if that is relevant to you.)
> 
> Why not simply
> 
>     #define PI2 6.28
> 

Yes, that would work too in this case.  But there is a general trend
that if something can be expressed as a typed constant value, rather
than a pre-process macro, then the const is to be preferred.  It has
better type safety, can be scoped (not relevant in this case), is less
prone to accidents (because you can only use it in places where that
type is appropriate), and plays better with IDEs/editors and debuggers.

People vary about which they prefer - with C++ folks often more strongly
on the "const" side, while C programmers are used to #define symbols.

[toc] | [prev] | [next] | [standalone]


#70499

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-09-14 14:52 +0100
Message-ID<JiAJx.429972$LU5.267266@fx12.am4>
In reply to#70497
On 14/09/2015 14:45, David Brown wrote:
> On 14/09/15 14:39, August Karlstrom wrote:
>>  On 2015-09-14 10:24, David Brown wrote:
>>>  On 14/09/15 05:50, Ian Collins wrote:
>>>>  Make the declaration in the header
>>>>
>>>>  extern const double PI2;
>>>>
>>>>  and define in in one and only one .c file
>>>>
>>>>  const double PI2 = 6.28;
>>>>
>>>
>>>  Alternatively, especially for simple constants, change the declaration
>>>  in the header file to the definition :
>>>
>>>  static const double PI2 = 6.28;
>>>
>>>  and remove any definition in .c files.
>>>
>>>  (There are differences in these two techniques, but in cases like yours
>>>  then either can usually be used.  Using a static const in the header
>>>  will often lead to more efficient code, if that is relevant to you.)
>>
>>  Why not simply
>>
>>      #define PI2 6.28
>>
>
> Yes, that would work too in this case.  But there is a general trend
> that if something can be expressed as a typed constant value, rather
> than a pre-process macro, then the const is to be preferred.

I don't really care either way.

Perhaps more importantly, unless your system supports VLAs, you can't 
use a typed constant value to define the size of an array. So if you use 
a typed value and find that you need a 6.28-element array of ints, 
you're stuffed.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#70510

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-14 18:13 +0200
Message-ID<mt6rnl$ho1$1@speranza.aioe.org>
In reply to#70499
On 2015-09-14 15:52, Richard Heathfield wrote:
> Perhaps more importantly, unless your system supports VLAs, you can't
> use a typed constant value to define the size of an array.

This is why I prefer to declare a compile-time constant as a... 
compile-time constant!


-- August

[toc] | [prev] | [next] | [standalone]


#70507

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-09-14 16:41 +0100
Message-ID<87egi1f1pu.fsf@bsb.me.uk>
In reply to#70497
David Brown <david.brown@hesbynett.no> writes:

> On 14/09/15 14:39, August Karlstrom wrote:
>> On 2015-09-14 10:24, David Brown wrote:
>>> On 14/09/15 05:50, Ian Collins wrote:
>>>> Make the declaration in the header
>>>>
>>>> extern const double PI2;
>>>>
>>>> and define in in one and only one .c file
>>>>
>>>> const double PI2 = 6.28;
>>>>
>>>
>>> Alternatively, especially for simple constants, change the declaration
>>> in the header file to the definition :
>>>
>>> static const double PI2 = 6.28;
<snip>
>> Why not simply
>> 
>>     #define PI2 6.28
>
> Yes, that would work too in this case.  But there is a general trend
> that if something can be expressed as a typed constant value, rather
> than a pre-process macro, then the const is to be preferred.  It has
> better type safety, can be scoped (not relevant in this case), is less
> prone to accidents (because you can only use it in places where that
> type is appropriate), and plays better with IDEs/editors and
> debuggers.

You mention twice safety twice, but 6.28 (the result of the #defined)
has the same type as PI2 defined as a const double.  The latter is an
lvalue (though not a modifyable one) but that's probably not important.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#70542

Fromdakupoto@gmail.com
Date2015-09-14 19:47 -0700
Message-ID<76c921fe-bb4d-4061-a4ff-129ccad0351b@googlegroups.com>
In reply to#70497
On Monday, September 14, 2015 at 9:45:14 AM UTC-4, David Brown wrote:
> On 14/09/15 14:39, August Karlstrom wrote:
> > On 2015-09-14 10:24, David Brown wrote:
> >> On 14/09/15 05:50, Ian Collins wrote:
> >>> Make the declaration in the header
> >>>
> >>> extern const double PI2;
> >>>
> >>> and define in in one and only one .c file
> >>>
> >>> const double PI2 = 6.28;
> >>>
> >>
> >> Alternatively, especially for simple constants, change the declaration
> >> in the header file to the definition :
> >>
> >> static const double PI2 = 6.28;
> >>
> >> and remove any definition in .c files.
> >>
> >> (There are differences in these two techniques, but in cases like yours
> >> then either can usually be used.  Using a static const in the header
> >> will often lead to more efficient code, if that is relevant to you.)
> > 
> > Why not simply
> > 
> >     #define PI2 6.28
> > 
> 
> Yes, that would work too in this case.  But there is a general trend
> that if something can be expressed as a typed constant value, rather
> than a pre-process macro, then the const is to be preferred.  It has
> better type safety, can be scoped (not relevant in this case), is less
> prone to accidents (because you can only use it in places where that
> type is appropriate), and plays better with IDEs/editors and debuggers.
> 
> People vary about which they prefer - with C++ folks often more strongly
> on the "const" side, while C programmers are used to #define symbols.

Thanks to each of you for these very helpful 
hints. I knew that there was some subtle problem somewhare, but kept missing it.

[toc] | [prev] | [next] | [standalone]


#70590

FromPaul N <gw7rib@aol.com>
Date2015-09-15 16:00 -0700
Message-ID<09279ef8-fa7a-4500-ac1e-281b35bd6e3c@googlegroups.com>
In reply to#70542
On Tuesday, 15 September 2015 03:47:45 UTC+1, daku...@gmail.com  wrote:
> On Monday, September 14, 2015 at 9:45:14 AM UTC-4, David Brown wrote:
> > On 14/09/15 14:39, August Karlstrom wrote:
> > > On 2015-09-14 10:24, David Brown wrote:
> > >> On 14/09/15 05:50, Ian Collins wrote:
> > >>> Make the declaration in the header
> > >>>
> > >>> extern const double PI2;
> > >>>
> > >>> and define in in one and only one .c file
> > >>>
> > >>> const double PI2 = 6.28;
> > >>>
> > >>
> > >> Alternatively, especially for simple constants, change the declaration
> > >> in the header file to the definition :
> > >>
> > >> static const double PI2 = 6.28;
> > >>
> > >> and remove any definition in .c files.
> > >>
> > >> (There are differences in these two techniques, but in cases like yours
> > >> then either can usually be used.  Using a static const in the header
> > >> will often lead to more efficient code, if that is relevant to you.)
> > > 
> > > Why not simply
> > > 
> > >     #define PI2 6.28
> > > 
> > 
> > Yes, that would work too in this case.  But there is a general trend
> > that if something can be expressed as a typed constant value, rather
> > than a pre-process macro, then the const is to be preferred.  It has
> > better type safety, can be scoped (not relevant in this case), is less
> > prone to accidents (because you can only use it in places where that
> > type is appropriate), and plays better with IDEs/editors and debuggers.
> > 
> > People vary about which they prefer - with C++ folks often more strongly
> > on the "const" side, while C programmers are used to #define symbols.
> 
> Thanks to each of you for these very helpful 
> hints. I knew that there was some subtle problem somewhare, but kept missing it.

Since David's mentioned C++, it perhaps worth pointing out that the rules in C++ are different, to the extent that your original technique would (I think) work in C++.

[toc] | [prev] | [next] | [standalone]


#70461

Fromgordonb.78i5t@burditt.org (Gordon Burditt)
Date2015-09-13 23:40 -0500
Message-ID<WpOdnXwqi_000mvInZ2dnUU7-YmdnZ2d@posted.internetamerica>
In reply to#70459
> Could some C guru please help ? I have the 
> following set of ".h" and ".c" files.
> A.h, B.h, C.h, B.c and C.c. A.h contains
> constants as:
> const double PI2 = 6.28;
> and so on.
> A.h is included in B.h.
> and B.h is included in 
> C.h 
> The main executable is C.c
> (contains int main(int argc, 
> char **argv)) and uses 
> utility functions defined 
> in B.c 

You forgot to say that B.h is included in B.c.

The line:

const double PI2 = 6.28;

which is a definition, not just a declaration, because PI2 is
initialized, should only appear in the *ONE* of the compilations
that you link together.  You have it in both, which causes the
"multiple definition" error below.  The same applies to PI, TOL,
TOLC, UCT, USW, AWGlwn, MCOL, MCOLC, MCOLRC, Cores, and AWG if they
are similar initialized data variables.

extern const double PI2;	/* Goes in a .h file */

const double PI2 = 6.28;	/* Goes in a .c file */
				/* which should include the .h file */
				/* Note:  this is a poor approximation */
				/* to 2*pi, especially for a double */


> I compile with the command 
> line:
> gcc -g -o C.c B.c -lm
> I get error messages as :
> /tmp/cckNfO8Q.o:(.rodata+0x0): multiple definition of `PI'
> /tmp/cc2ggMjE.o:(.rodata+0x0): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x8): multiple definition of `PI2'
> /tmp/cc2ggMjE.o:(.rodata+0x8): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x10): multiple definition of `TOL'
> /tmp/cc2ggMjE.o:(.rodata+0x10): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x18): multiple definition of `TOLC'
> /tmp/cc2ggMjE.o:(.rodata+0x18): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x20): multiple definition of `UCT'
> /tmp/cc2ggMjE.o:(.rodata+0x20): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x28): multiple definition of `USW'
> /tmp/cc2ggMjE.o:(.rodata+0x28): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x30): multiple definition of `AWGlwn'
> /tmp/cc2ggMjE.o:(.rodata+0x30): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x34): multiple definition of `MCOL'
> /tmp/cc2ggMjE.o:(.rodata+0x34): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x38): multiple definition of `MCOLC'
> /tmp/cc2ggMjE.o:(.rodata+0x38): first defined here
> /tmp/cckNfO8Q.o:(.rodata+0x3c): multiple definition of `MCOLRC'
> /tmp/cc2ggMjE.o:(.rodata+0x3c): first defined here
> /tmp/cckNfO8Q.o:(.data+0x0): multiple definition of `Cores'
> /tmp/cc2ggMjE.o:(.data+0x0): first defined here
> /tmp/cckNfO8Q.o:(.data+0x1ac0): multiple definition of `AWG'
> /tmp/cc2ggMjE.o:(.data+0x1ac0): first defined here
> collect2: ld returned 1 exit status
> 
> Could some one please 
> provide some hints as
> to what is going wrong.
> Thanks in advance.
>   
>    
> 

[toc] | [prev] | [next] | [standalone]


#70989

FromIke Naar <ike@iceland.freeshell.org>
Date2015-09-20 20:24 +0000
Message-ID<slrn3vfsmvu5k6.l8q.ike@iceland.freeshell.org>
In reply to#70459
On 2015-09-14, dakupoto@gmail.com <dakupoto@gmail.com> wrote:
> Could some C guru please help ? I have the 
> following set of ".h" and ".c" files.
> A.h, B.h, C.h, B.c and C.c. A.h contains
> constants as:
> const double PI2 = 6.28;
> and so on.
> A.h is included in B.h.
> and B.h is included in 
> C.h 
> The main executable is C.c
> (contains int main(int argc, 
> char **argv)) and uses 
> utility functions defined 
> in B.c 
> I compile with the command 
> line:
> gcc -g -o C.c B.c -lm

Are you sure the '-o C.c' part of the command line is correct?
It instructs gcc to create an output file named C.c .

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web