如何避免多功能定义(Linux,GCC / G ++,Code :: Blocks)

时间:2013-07-22 14:16:29

标签: c++ header codeblocks

我在代码块中有一个项目,它使用许多不同的文件 - 通常由其他程序员编写。目前我的情况是,我有两个不同的子项目,包含以相同方式命名的函数。比方说:F(int x)。所以F(int x)在两个不同位置的两个源文件中定义,它们有两个不同的头。我还为这些标题创建了两个不同的名称空间:

namespace NS1
{
 extern "C"{
  #include "header1definingF.h"
 }
}
namespace NS2
{
 extern "C"{
  #include "header2definingF.h"
 }
}

但是仍然编译器抱怨它有多个F(int x)的定义。我如何在Code :: Blocks中解决这个问题(在Visual Studio中它可以正常工作)。

编辑:更清楚的是,这些标题包含C代码。我没想到它会如此凌乱。有数千个源文件使用其他项目,包括数以千计的功能......所以该怎么做。我完全不知道如何让它发挥作用。

6 个答案:

答案 0 :(得分:4)

我想知道为什么它适用于Visual Studio,但不适用于代码块。这表明你确实有一个包含守卫。 this有帮助吗?

Project->Build options...->Linker settings (tab)
-Wl,--allow-multiple-definition

答案 1 :(得分:3)

问题是名称空间不适用于C函数(extern“C”)。 这是一个不编译的简单示例:

namespace NS1
{
 extern "C"{
  int f()
  {
   return 1;
  }
 }
}
namespace NS2
{
 extern "C"{
  int f()
  {
   return 2;
  }
 }
}

在这种情况下,两个函数不同但名称相同:f()。如果您只是声明函数,它将编译,但它们必须引用相同的函数。

这第二个样本工作正常。这些函数的名称为NS1 :: f()和NS2 :: f(),它们是不同的。

namespace NS1
{
 int f()
 {
  return 1;
 }
}
namespace NS2
{
 int f()
 {
  return 2;
 }
}

如果你想使用两个不同的c代码,你可以使用objcopy来帮助你拥有一个NS1_f()和NS2_f()函数。之后,您应该重命名包含中库的所有功能。在这种情况下,不使用命名空间。这是正常的,C中没有名称空间。等价函数:

int NS1_f()
{
 return 1;
}
int NS2_f()
{
 return 2;
}

答案 2 :(得分:2)

我无法清楚地理解你的问题,但我认为你应该理解编译器是如何工作的,当你使用gcc来强制你的程序时,你的程序首先会运行include运算符,这意味着如果你包含一个头,那么编译器会将头文件复制到该文件中。如果你包括两次标题会有两次定义错误。所以你必须保证一次,你可以使用

#ifndef __FILE_NAME__
#define __FILE_NAME__
// your code
#endif

如果您的问题是重新定义函数,您应该知道编译器如何区分函数,我认为您的问题是您在使用函数时不使用命名空间。

答案 3 :(得分:1)

我相信您还必须编辑cpp文件以将两个函数嵌套到相应的命名空间中。另外,您必须选择要调用的函数,如namespace::function(),或者可以将using namespace与您创建的任一命名空间一起使用。希望这有帮助!

[更新#1]更容易混淆函数的声明定义。请记住,您可以重新声明非成员函数。因此,如果头文件仅包含非成员函数声明,则可以在一个转换单元(cpp文件)中多次包含它。在头文件中添加ifndef / define是避免潜在问题的好习惯,但这并不能解决您的问题。

你的问题是你想要有两个不同的函数定义,它们具有相同的函数签名(它的名称和参数),并且在C ++中是不允许的。您可以更改其中一个签名,也可以将它们放入不同的命名空间(您正在尝试但不触及其定义)。两种方式都要求您编辑包含其定义的文件。

[更新#2] 当您使用C代码更新问题时,我已经搜索并找到了这个:

What should I do if two libraries provide a function with the same name generating a conflict?

它肯定会帮助您更清楚地了解您的问题并找到解决方案。祝你好运!

答案 4 :(得分:1)

除了编辑.cpp文件本身并重命名函数(这不是一个实际的解决方案)之外,您的选项要么确保一次只包含一个具有重复功能的头文件(这可能是一个巨大的维护问题)或者,这是我的建议,使用名称空间。在这种情况下,它们可以为您节省大量的麻烦。

答案 5 :(得分:1)

您可能需要两件事之一。以下称为 Header Guard

#ifndef MYHEADER_H
#define MYHEADER_H

//your header code goes here

#endif

这样,每个请求它的目标文件只包含一次标题。但是,如果您希望两个方法具有相同的标识符,则它们必须属于不同的命名空间

namespace myspace1{
    void func(void);
};
namespace myspace2{
    void func(void);
};

除此之外,你可以做的其他事情并不多。你不应该有两个同名的功能一般。此外,您必须在您提到的头文件中修改它。

您可以根据需要随时声明功能,但只能有 ONE 定义。