首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gcc多重definition...release

gcc多重definition...release
EN

Stack Overflow用户
提问于 2013-11-05 09:06:34
回答 4查看 1.3K关注 0票数 2

我在头文件中定义了一个函数。在调试中,它编译并链接良好。在发行版中,对于包含头的每个类的每个对象文件,我都会得到编译错误“‘blah::blah(blah&blah)’的多个定义”。

我用gcc-4.8.1。我不能发布实际的代码,这个版本更改了名称以保护无辜的人:

代码语言:javascript
复制
#ifndef INCLUDE_SMELLS_FUNNY
#define INCLUDE_SMELLS_FUNNY

#include "ParentClass.h"
#include "ChildClassA.h"
#include "ChildClassB.h"

namespace someplace {

bool smellsFunny(const ParentClass& someData) {

  // All ChildClass As smell funny
  if(dynamic_cast<const ChildClassA*>(&someData)) {
    return true;
  }

  // If ChildClass B, need to check if smells funny
  const ChildClassB* childB = dynamic_cast<const ChildClassB*>(&someData)
   if(childB) {
    return childB->MoreThanAWeekOld();
  }

  // Default is smells OK
  return false;
}

}

#endif // INCLUDE_SMELLS_FUNNY

我还没找到是哪一面gcc的旗子。当然,修复只是将实现移动到cpp文件中。但为什么有这个必要呢?为什么只有在发布时才会发生这种情况?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-11-05 09:09:14

我不能确切地说,但是在调试模式下,函数被认为是内联函数。

票数 1
EN

Stack Overflow用户

发布于 2013-11-05 09:08:37

由于您已经将函数定义放置在标头中,所以需要将其标记为inline

代码语言:javascript
复制
inline bool smellsFunny(const ParentClass& someData) { ...

这是因为包含标头的每个地方都有函数的定义,从而打破了“一个定义规则”(ODR)。inline允许您绕过ODR。

至于为什么在发布模式中没有问题,这是没有意义的:代码是不正确的。可能是发布模式是为您内联声明函数。

票数 2
EN

Stack Overflow用户

发布于 2013-11-05 09:08:49

这是因为您在头文件中定义了函数,然后将该头文件包含在多个源文件中。这意味着函数将定义在每个源文件中(从技术上讲,翻译单元),其中包含标头。

对此有几种解决方案:

  1. 将函数标记为static。这意味着翻译单位中的每个定义都不会被导出。
  2. 将函数标记为inline。这基本上和第一种选择是一样的。
  3. 将函数的定义放在源文件中,并且只在头文件中声明它。

对于一个像你这样的小函数来说,备选方案2可能是个好函数。如果您有一个更大的函数,这是很难内联的,您应该使用备选方案3。

另外,如果使用数字3,则不需要包含头文件,然后减少循环包含的风险。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19785173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档