c++ - 在两个 cpp 文件中使用相同签名定义的本地函数。为什么他们应该彼此可见?

标签 c++ uniqueidentifier

为什么我在 Eclipse 中收到关于同一函数有两个定义的错误:

int readPath(const String &destDir, String &pathToFile) {/*Filler*/}

一个是旧版本(或新版本),我暂时放弃以专注于另一个版本。我想再次将它保存在我的项目目录中。

我可以移动它,但我不认为 cpp 文件中的标识符应该冒与其他 cpp 文件中的标识符发生命名冲突的风险,除非您实际上是 #include'ing 那些 cpp 文件,我不是。

最佳答案

I'm more concerned with why this should happen

因为这就是 C++(和 C)的工作方式。

这个:

int readPath(const String &destDir, String &pathToFile);

是一个函数声明。它告诉编译器,“在我的代码中的某处,在这个翻译单元或另一个中,将存在一个名为 readPath 的函数,它将作为参数......”这就是你放在头文件中的内容。

这个:

int readPath(const String &destDir, String &pathToFile) {/*Filler*/}

是一个函数定义。定义不只是简单地告诉编译器某些东西“将存在”。它告诉编译器它存在于这里,下面是它的工作原理。

命名空间范围(在全局命名空间或命名空间中)函数和变量的定义可以有两种链接。具有内部链接的定义意味着定义只对那个特定的翻译单元有效。其他翻译单元中的代码不能直接访问具有内部链接的函数或变量。

具有外部链接的定义意味着任何翻译单元都可以直接访问定义。它所需要的只是一种关闭编译器的方法。这就是声明的作用:告诉编译器“别担心:其他人会为你定义它。”

函数和变量默认为外部 链接。这是迄今为止最常见的情况。关键字 static 用于为函数和变量提供内部链接。

就此而言,单一定义规则要求具有外部链接的函数和变量在已编译和链接的程序中恰好一次 翻译单元中定义。如果两个翻译单元定义同一个函数,那么它们就违反了一个定义规则。

使用 inline 函数时,ODR 规则放宽了。这些可以在多个翻译单元中定义,但前提是每个人的实现都相同。

One is an old version (or new) that I dropped temporarily to focus on another version. I'd like to keep it in my project directory again.

以下是您的选择:

  1. 在匿名命名空间(没有名称的命名空间)中定义函数。根据 C++ 定义,所有匿名 namespace 都具有唯一的名称。所以在两个不同的匿名命名空间中定义的符号是不可能发生冲突的。
  2. #define 围绕旧的实现。使用#ifdef 实质上将其关闭。这是一种保留旧代码的历史悠久的技术。
  3. 走出黑暗时代,学习使用版本控制。旧代码属于以前版本的文件,现在不会弄乱您的文件。如果您想再次找到它们,请标记这些文件和修订版。

关于c++ - 在两个 cpp 文件中使用相同签名定义的本地函数。为什么他们应该彼此可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9285636/

相关文章:

c++ - 如何以跨平台的方式获取(几乎)唯一的系统标识符?

ios - 供应商标识符在 iOS 5.0 版中不起作用

python - 如何在python中获取azure函数的唯一实例id?

c++ - 模板函数中需要什么类型的迭代器?

c++ - 将功能添加到窗口顶部的主菜单

C++AMP 在 16 位图像上使用纹理计算梯度

javascript - javascript/jquery 中的 uniqid()?

sql-server - SQL Server 中的 guid 实际上是如何存储和排序/比较的?

java - Jace::虚拟机关机错误

c++ - 如何使用 pragma