struct方法链接

时间:2010-03-25 15:29:42

标签: c++ gcc

我正在更新一些旧代码,这些代码有几个POD结构,它们被memset归零(不要责怪我......我没有写这部分)。部分更新将其中一些更改为使用私有内部指针的类,这些指针现在已被memset消除。

所以我在各种结构中添加了[非虚拟] reset()方法,并重构了代码来调用它。

一个特定的结构体开发了一个“未定义的引用`blah :: reset()'”错误。

将其从结构更改为类可修复错误。

在.o文件h上调用nm,该方法的受损函数名称看起来是相同的(无论是类还是结构)。

我在Ubuntu上使用g ++ 4.4.1。

我讨厌这可能是编译器/链接器错误,但我不确定它可能是什么。我错过了结构和类之间的一些根本区别吗?我认为唯一有意义的是公共/私人默认以及每个人对它们的看法。

更新: 它实际上取决于它的声明方式:

typedef struct
{
  ...
  void reset();
} foo;

不会链接。

struct foo
{
  ...
  void reset();
};

很好。

那么,也许只是缺乏对typedef在这种情况下工作方式的理解?

2 个答案:

答案 0 :(得分:2)

认为你的问题(我没有标准引用来支持这个)是因为你的结构没有名字,你的成员函数也没有全球可识别的名称。

虽然您可以使用typedef名称来引入成员函数定义,但如果您希望能够将其链接到不同TU中的定义,则该成员函数必须是命名类型的一部分。

typedef struct S_ { void reset(); } S;

void S::reset() // OK, but the function actually has id: S_::reset()
{
    // ...
}

typedef struct { void reset(); } T;

void T::reset() // OK, defintion of anonymous struct's reset(),
                // but this isn't an id that can cross TUs.
{
    // ...
}

编辑:但这可能是一个gcc错误。

7.1.3 [dcl.typedef]如果typedef声明定义了未命名的类(...),则声明声明的第一个 typedef-name 是该类类型(... )用于表示类型(...)仅用于链接目的(3.5)。

修改

或者gcc可能是对的。虽然类通过其typedef名称(3.5 / 4)具有外部链接,但只有当类名称具有外部链接时,成员函数才具有外部链接。虽然该类具有外部链接,并且它具有用于链接目的的名称,但它仍然是未命名的类,因此它的成员函数没有链接。

答案 1 :(得分:1)

当然,第二个声明是“适当的”C ++做事方式。不过,这个链接对我来说是g ++ 4.4.1:

typedef struct {
    void f() {}
} S;


int main() {
    S s;
    s.f();
}

我必须承认整个结构命名空间对我来说一直是C的黑暗角落之一,但我相信其他人会想出一个解释。

编辑:确定,可以重现问题的极简主义代码:

// str.h
typedef struct {
    void f();
} S;

// str.cpp
#include "str.h"     
void S :: f() {
}

// sm.cpp
#include "str.h"    
int main() {
    S s;
    s.f();
}

编译:

g++ sm.cpp str.cpp

错误:

undefined reference to S::f()

现在,如果有人能够从标准中给出章节和经文,说明为什么这不起作用 - 显然是一个结构命名空间问题,我会想到。