c++ - 匿名命名空间在这里导致 undefined reference - 在那里工作

标签 c++ gcc g++ embedded keil

我已经为嵌入式系统编写了一些 C++ 代码,效果非常好。当前的任务是在 PC 上模拟此设备的行为。一些代码必须移植:对于第一次测试,我使用 mingw (g++),而嵌入式系统是 STM32 并使用 KEIL µVision 工具链。

我遇到了一个与功能行为无关的问题,而不是编译器特定的怪异问题。我在匿名命名空间中定义了 2 个类,因为它们包含在整个项目中。现在在嵌入式设备上编译和运行没有问题。 g++ 提示 undefined reference !

当我删除类周围的匿名命名空间时,它会编译并运行!但为什么?下面是一些重现这种情况的示例代码: main.cpp :

#include "notmain.h"
#include "theclass.h"

A *ourA=NULL;

int main()
{
    theA = new A();
    theA->dostuff(1024);
    sunshine sun;
    sun.Init();
}

notmain.cpp:

#include "notmain.h"
#include "theclass.h"

void sunshine::Init()
{
    theA->dostuff(127);
}

notmain.h:

#ifndef NOTMAIN_H_
#define NOTMAIN_H_
class sunshine
{
public:
    void Init();
};
#endif

类.h:

#ifndef THECLASS_H_
#define THECLASS_H_
#include <stdio.h>
#define theA ourA
namespace
{
    class A
    {
    public:
        void dostuff(int b)
        {
            a = b;
            printf("Hello: %d\n",a);
        }
    private:
        int a;
    };
}
extern A *ourA;
#endif

编译器/链接器输出: 09:09:57 ** 项目 Testo 的配置调试增量构建 ** 信息:Internal Builder 用于构建 g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\main.cpp" g++ -O0 -g3 -Wall -c -fmessage-length=0 -o notmain.o "..\notmain.cpp" g++ -o Testo.exe notmain.o main.o notmain.o:在函数 ZN8sunshine4InitEv' 中: D:\Projekte\Testo\Debug/../notmain.cpp:6: undefined reference ourA' collect2.exe:错误:ld 返回了 1 个退出状态

09:09:57 Build Finished (took 702ms)

删除该 namespace 可以解决问题,但为什么它在 KEIL 中编译、链接和工作?谁能给我解释一下?

最佳答案

我认为这是对匿名命名空间功能的滥用。它与您要实现的目标完全相反。

匿名命名空间用于将定义本地化到单个翻译单元。如果您将一个放在头文件中,然后将该头文件包含在多个翻译单元中,这将导致您的代码中出现多个独立的定义。

这里 VC++ 发生的事情是全局 ourA 已被实例化为指向 main.cpp 中定义的 A 的一个局部定义的指针,然后 local 定义不再可见,但与 notmain.cpp 中当前可见的本地版本不同。 ZN8sunshine4InitEv 的name mangling 区分了独立的定义,但是name mangling 是编译器定义的,我猜想ARM 的RealView 编译器(uVision 使用)有一个不同的方案,无法发现这个错误。

如果这个错误出现在 RealView 中,实际上并不清楚结果是什么,但它不可能是正确的,或者至少是定义明确的。

RealView 实际上在发出其他编译器通常会发出的警告方面相当差,并且在我发现的未定义行为方面有点宽容。始终值得使用其他工具链,例如带有 -Werror -Wall 的 MinGW/GCC 或使用静态分析工具来清理您的代码。

要解决这个问题,您应该使用明确命名的命名空间,或者根本不使用命名空间。

关于c++ - 匿名命名空间在这里导致 undefined reference - 在那里工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22955470/

相关文章:

linux - 主要和堆栈对齐

c++ - Visual C++ 2008 和 g++ 的区别

c++ - 使用 gdb 附加到尚未启动的进程

C++:析构函数需要 "if"语句吗?

c++ - 我可以要求用户重新输入命令行参数吗

linux - 使用较低版本的 GLIBC : version `GLIBC_2.11` not found (required by g++)

c++ - 为什么一个类方法在其对象文件中不存在而其他方法存在?

android - 无法使用套接字显示接收到的缓冲区

c++ - Python C++ API : How to access public class attribute?

c++ - 使用 ** 更改地址的值