c++ - 匿名命名空间和单一定义规则

标签 c++ namespaces one-definition-rule

我是否违反了以下程序的单一定义规则?

// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_

namespace {
   inline int foo() {
       return 1;
   }
}

inline int bar() {
    return foo();
}
#endif
//EOF

// m1.cpp

#include "foo.hpp"

int m1() {
    return bar();
}

//EOF

// m2.cpp

#include "foo.hpp"

int m2() {
    return bar();
}

//EOF

最后

// main.cpp
#include <iostream>

int m1();
int m2();

int main(int, const char* [])
{
    int i = m1();
    int j = m2();

    std::cout << (i+j) << std::endl;
    return 0;
}

// EOF

在上面,注意 foo() 是在匿名命名空间中定义的,所以我希望每个翻译单元 m1.cppm2.cpp 将获得自己的版本,因此不会违反 ODR。另一方面,bar() 只是一个普通的旧内联函数,它恰好调用了 2 个不同的 foo。所以它违反了 ODR,对吧?

更新: 以前我在 foo 的定义中有宏,它改变了它返回的值,每个 m1m2 在包含 之前定义了不同的宏>foo.hpp。 (在前面的示例中,g++ 会生成一个二进制文件,输出 (i+j) 的值与您期望的值不同。)但实际上即使 foo() 的主体相同,该程序也违反了 ODR。

最佳答案

这确实违反了 ODR。请参阅 3.2/5 讨论外部内联函数 (bar):

in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity...

在这种情况下,bar指的是两个不同版本的foo,因此违反了规则。

关于c++ - 匿名命名空间和单一定义规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7955058/

相关文章:

c++ - 在 C++ 中进行 'constify' 操作有意义吗?

php - 命名空间中断调用 Composer 导入的类

c++ - 标准在哪里指定类内定义的函数是内联的?

c++ - 声明一个静态常量和一个常量到未命名的命名空间有什么区别?

php - 升级到 Laravel 5 后的命名空间问题

c++ - 在 .h 文件包含在多个 cpp 文件中的类中定义 integral static const

c++ - 关于ODR、声明和定义的一些问题

c++ - 崩溃的程序和挂起的程序之间的区别

C++ LibCurl - 将 CURLcode 转换为 CString

c# - 仅存在于任务栏中的 Windows 应用程序