gcc报错 “multiple definition of ‘funname'”,然后如何声明全局字符数组?

huangapple go评论56阅读模式
英文:

gcc complaining "multiple definition of 'funname' ", then how to declare a global character array?

问题

我打算在error.h中声明funname全局字符数组,并在所有*.c文件中包含这个头文件。funname用于存储最新发生错误的函数名称(内置错误和我自定义的错误)。每个有可能生成错误的函数都将其名称分配给funname,如下所示:

//文件名:someSourcecode.c

#include "error.h"

int fun1(int a, float b)
{
    strcpy(funname, "fun1");

    if (someUnexpectedEvent)
    {
        errno = MyOwnDefinedMacroWithIntegerValue;
        return -2;
    }
}

我还有一个error.c文件,用于打印其相应的errno的错误消息。printerrorerror.c中打印这些错误消息的函数,其定义如下:

//文件名:error.c

#include "error.h"

void printerror()
{
    if (errno == USERUNAVAILABLE)  //自定义的errno值
    {
        fprintf(stderr, "Error:  %s   user is unavailable\n", funname);
    }

    ... //等等
}

我的问题是:

  • 如果我在error.h文件中全局声明它如下:
    char funname[1024] = "";
    我的各个*.c文件可以编译(每个*.c文件都使用gcc -c file1.c命令进行编译)而没有任何错误,但是当我尝试一次性链接它们全部(gcc file1.o file2.o file3.o file4.o main.o -o bin)时,它会显示以下错误:

    /usr/bin/ld: bin/file1.o:(.bss+0x0): multiple definition of 'originFuncName'; bin/main.o:(.bss+0x0): first defined here
    /usr/bin/ld: bin/file2.o:(.bss+0x0): multiple definition of 'originFuncName'; bin/main.o:(.bss+0x0): first defined here
    /usr/bin/ld: bin/error.o:(.bss+0x0): multiple definition of 'originFuncName'; bin/main.o:(.bss+0x0): first defined here
    /usr/bin/ld: bin/file3.o:(.bss+0x0): multiple definition of 'originFuncName'; bin/main.o:(.bss+0x0): first defined here
    /usr/bin/ld: bin/file4.o:(.bss+0x0): multiple definition of 'originFuncName'; bin/main.o:(.bss+0x0): first defined here
    
  • 如果我像这样在全局声明:
    static char funname[1024] = "";
    然后编译和链接没有问题,它也能正常运行,但是,在打印错误消息时,函数名称未打印出来,可能会打印空字符串作为函数名称。

我应该怎么办?

英文:

I have a header error.h, and this is where I want to declare my global character array funname.

My idea is to declare funname in error.h, and include this header in all of my *.c files. funname stores the function name in which the latest error occured (in-built error + my own defined errors). Every function which has a potential to generate error assigns its name to funname like this:

//filename: someSourcecode.c

#include "error.h"

int fun1(int a, float b)
{
    strcpy(funname, "fun1");

    if(someUnexpectedEvent)
    {
        errno = MyOwnDefinedMacroWithIntegerValue;
        return -2;
    }
}

I also have error.c file which prints error messages for their respective eerno. printerror is the function in error.c which prints those error messages and that function is defined like this:

//filename: error.c

#include "error.h"

void printerror()
{
    if(errno == USERUNAVAILABLE)  //own defined errno value
    {
        fprintf(stderr, "Error:  %s   user is unavailable\n", funname);
    }

    ... //and so on
}

My Problem:

in error.h file, if I declare it like this (globally)-
char funname[1024] = ""; , my invidual *.c compiles (each *.c file is compiled with command gcc -c file1.c) compiled without any error but when I tried to link them all at once (gcc file1.o file2.o file3.o file4.o main.o -o bin), it showed error like this:

/usr/bin/ld: bin/file1.o:(.bss+0x0): multiple definition of `originFuncName'; bin/main.o:(.bss+0x0): first defined here
/usr/bin/ld: bin/file2.o:(.bss+0x0): multiple definition of `originFuncName'; bin/main.o:(.bss+0x0): first defined here
/usr/bin/ld: bin/error.o:(.bss+0x0): multiple definition of `originFuncName'; bin/main.o:(.bss+0x0): first defined here
/usr/bin/ld: bin/file3.o:(.bss+0x0): multiple definition of `originFuncName'; bin/main.o:(.bss+0x0): first defined here
/usr/bin/ld: bin/file4.o:(.bss+0x0): multiple definition of `originFuncName'; bin/main.o:(.bss+0x0): first defined here

And if I declare like this (globally)- static char funname[1024] = "";, then I don't have any problem in compiling and linking, it also runs properly, except, when error message is print, the function name is not printed, probably printing null string as function name.

What should I do?

答案1

得分: 1

这个声明

char funname[1024] = "";

也是变量 funname 的定义。因此,如果在多个翻译单元中包含了该头文件,那么将会有多个相同变量的定义。

你应该在头文件中声明变量,例如:

extern char funname[1024];

然后在某个模块中定义它,比如:

char funname[1024] = "";

至于这个声明

static char funname[1024] = "";

那么变量 funname 具有内部链接。这意味着每个包含该头文件的翻译单元都将有自己独立的变量。

英文:

This declaration

char funname[1024] = "";

also is a definition of the variable funname. Thus if the header is included in several translation units then you will have multiple definitions of the same variable.

You should declare the variable in the header like for example

extern char funname[1024];

and then define it in some module like

char funname[1024] = "";

As for this declaration

static char funname[1024] = "";

then the variable funname has internal linkage. It means that every translation unit where the header is included will have its own separate variable.

huangapple
  • 本文由 发表于 2023年1月9日 03:50:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定