11

我无法理解下面的编译错误。

第一个文件是标题,test_weak.h

#ifndef TEST_WEAK_H
#define TEST_WEAK_H
    #ifndef __ASSEMBLER__
const char* const TUTU __attribute__((weak)) ="TUTU";
const char* TUTU_DATE __attribute__((weak)) = __DATE__;
const char* const tutu ="tutu";
    #endif /*ASSEMBLER*/
#endif /*TEST_WEAK_H*/

第二个文件是主要的test.cpp

int main ()
{
  return 42;
}

要编译我运行:g++ -include test_weak.h test.cpp -o test

编译结果为:

 In file included from <command-line>:0:0:
./test_weak.h:5:44: error: weak declaration of ‘TUTU’ must be public

通过在测试源文件上用 c 扩展名替换 cpp 扩展名并使用 gcc 而不是 g++,我能够成功运行此代码。我还可以通过删除弱属性或删除第二个常量来修复此错误。所以是的,我能够修复编译错误,但无法在这里理解问题的原因。

例如这一行编译没有问题:

const char* TUTU __attribute__((weak)) ="TUTU";

为什么我不能const char* const在 c++ 中使用 + 弱属性?

4

2 回答 2

12

weak属性告诉链接器如何处理不同翻译单元中同一实体的多个定义。在 C++ 中,为了使其相关,实体必须具有外部链接——这就是链接器所指的“公共”。在 C++ 中,默认情况下,本身const具有内部链接的变量。你可能想要的是:

extern char const* const TUTU __attribute__((weak)) = "TUTU";

形式上,这将是 C++ 中未定义的行为(没有 __attribute__,它不是 C++)。弱属性的目的是允许它,所有实例共享相同的内存(如果任何实例具有不同的初始化程序,它将导致未定义的行为,或者至少未指定。

实际上:您可能想要的是:

extern char const TUTU[] __attribute__((weak)) = "TUTU";

毫无意义地引入指针。

编辑:

请注意,这是 C 和 C++ 之间的差异之一。在 C 中,const对链接没有影响。

于 2013-10-21T10:37:08.493 回答
5

const在 C++ 中,已声明但未显式声明的变量extern接收内部链接(即,如同已声明一样static)。显然这不能与weak属性结合。

C 没有此规则,因此符号获得外部链接,因此当您将其编译为 C 代码时,可以将属性应用于它。

于 2013-10-21T10:36:06.320 回答