getopt.c: optarg should not be initialized

Richard Earnshaw rearnsha@arm.com
Wed Sep 22 23:30:00 GMT 2010


On Wed, 2010-09-22 at 15:07 +0200, Christophe Lyon wrote:
> On 22.09.2010 13:47, Schwarz, Konrad wrote:
> > Christophe,
> >
> > could you explain your problem in more detail,
> > with an example, perhaps?
> >
> Here is a reduced test (I hope it's not too reduced)
> 
> ========= main.c =========
> #include <stdio.h>
> 
> extern char *optarg;
> extern int optind, opterr, optopt;
> 
> int getopt(int argc, char * const argv[],
> 	   const char *optstring);
> 
> int main()
> {
>    printf("Hello\n");
>    return 0;
> }
> ======= getopt.c =========
> char *optarg;
> 
> int optind = 1;
> int opterr = 1;
> int optopt = '?';
> 
> int getopt(int argc, char * const argv[],
> 	   const char *optstring)
> {
>    optarg = 0;
>    return -1;
> }
> 
> ===========================
> I am using an ARM-bare machine GCC + Newlib (Code Sourcery 2010q1) like 
> this:
> $ arm-none-eabi-gcc -c getopt.c
> $ arm-none-eabi-gcc -c main.c
> $ arm-none-eabi-gcc getopt.o main.o -o main -T generic-hosted.ld
> [...]/arm-none-eabi/lib/libc.a(lib_a-getopt.o): In function `getopt':
> getopt.c:(.text+0x97c): multiple definition of `getopt'
> getopt.o:getopt.c:(.text+0x0): first defined here
> [...]/arm-none-eabi/lib/libc.a(lib_a-getopt.o):(.bss+0x4): multiple 
> definition of `optind'
> getopt.o:(.data+0x0): first defined here
> [...]/arm-none-eabi/lib/libc.a(lib_a-getopt.o):(.data+0x0): multiple 
> definition of `opterr'
> getopt.o:(.data+0x4): first defined here
> [...]/arm-none-eabi/lib/libc.a(lib_a-getopt.o):(.data+0x4): multiple 
> definition of `optopt'
> getopt.o:(.data+0x8): first defined here
> collect2: ld returned 1 exit status
> 
> I don't think it's obvious that initializing optarg will make the linker 
> happy.
> 
> To make it clear, in this precise case, optarg is COMMON in the user 
> getopt.o, and because it is DEFINED in libc.a(getopt.o), the linker 
> decides to link with libc.a(getopt.o), leading to multiple definitions. 
> If the optarg from libc.a(getopt.o) was COMMON too, the libc.a(getopt.o) 
> module wouldn't be pulled by the linker, thus avoiding the multiple 
> definitions.
> 
> I think this is a bit opaque for the average user.
> 
> Christophe.

This is another reason why COMMON is evil.  Build your code with
-fno-common and the problem will go away.  You'll sometimes get better
code if you do that too as the compiler can reason about the placement
of objects (which it can't do if they're common).

R.



More information about the Newlib mailing list