问题标签 [one-definition-rule]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
124 浏览

c++ - 关于 odr-used 定义的一点误解

odr-used 变量的定义如下:

变量 x 其名称显示为潜在求值表达式 ex 是 odr-used 除非 x 满足出现在常量表达式 (5.19) 中的要求,并且,如果 x 是一个对象,ex 是一组潜在结果的元素表达式 e,其中左值到右值的转换 (4.1) 应用于 e,或者 e 是丢弃值表达式(第 5 条)。

据我了解ex,可以是任何包含x作为潜在评估操作数的表达式,例如,x++

但我不明白e在那种情况下是什么。

0 投票
1 回答
181 浏览

c - Typedef,违反 ODR:相同的关键字别名不同的类型

我需要链接 2 个库。第一个库需要一个头文件,其中:

第二个库需要一个头文件,其中:

显然,将它们链接会导致违反单一定义规则 (ODR)。这里明显的解决方案是重命名其中一种类型。但是,这也需要我在数百个文件中进行更改,我试图避免这种情况,因为它会使我们所有的项目不一致。有没有其他方法可以克服这个问题?

0 投票
1 回答
148 浏览

c++ - 强制初始化模板类的静态数据成员

关于模板类的静态数据成员未初始化的一些问题。不幸的是,这些都没有能够帮助我解决我的具体问题的答案。

我有一个模板类,它有一个静态数据成员,必须为特定类型显式实例化(即必须专门化)。如果不是这种情况,使用不同的模板函数应该会导致链接器错误。

这是一些代码:

调用runme<T>应该要求它Instantiate<T>::instance被定义,而不是实际使用它。得到一个instance如图所示的指针是可行的——但前提是没有启用优化。我需要一种至少可以使用的不同方法O2,并且如果 的实例化instance发生在不同的编译单元中也可以使用。

问题:如何确保在使用未明确定义/专门化runme的类型调用时出现链接器错误?TInstantiate<T>::instance

0 投票
2 回答
5171 浏览

c++ - 访问静态 constexpr 浮点成员时未定义的引用

此代码有效:

但是,如果我更改int为,float我会收到一个错误:

/tmp/main-272d80.o:在函数main': main.cpp:(.text+0xe): undefined reference toBlob::a'

为什么我不能constexpr float以那种方式使用 a ?

编译器:Ubuntu clang 版本 3.5.0-4ubuntu2 (tags/RELEASE_350/final)

在 gcc 版本 4.9.1 (Ubuntu 4.9.1-16ubuntu6) 上测试,没有错误。

编辑:

如果我使用 -O1、-O2、-O3 或 -Os,它将编译,但使用 -O0 失败

0 投票
0 回答
67 浏览

c++ - C++ 是否允许未使用的变量有多个定义?

给定一个源文件

和另一个源文件

实现通常拒绝这一点,这对我来说很有意义,即使a未使用。

但是,我找不到标准在哪里说这是一个错误。

在 C 中,这由(强调我的)涵盖:

6.9 外部定义

5外部定义是一个外部声明,它也是函数(内联定义除外)或对象的定义。如果用外部链接声明的标识符在表达式中使用(而不是作为sizeof结果为整数常量的运算符的操作数的一部分),则在整个程序的某处,该标识符应该只有一个外部定义;否则,不得超过一个。

由于这出现在约束之外,在 C 中,行为只是未定义的。允许实现拒绝它,或者允许它们在没有警告的情况下默默地接受它,在这种情况下,不保证行为。我很确定 C++ 的意图是相同的。

我可以在 [basic.def.odr] 中的 C++ 标准中找到“在整个程序中的某个地方,标识符应该只有一个外部定义”的等价物:

3.2 一个定义规则[basic.def.odr]

4 每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义;无需诊断。[...]

但是,我找不到涵盖未使用 odr 的对象或功能的措辞。标准是否在任何地方指定这是一个错误?如果有,在哪里?

[basic.def.odr] 还包含对某些类型的实体的限制,这些实体通常可以在 p6 中具有多个定义,有效地说明所有定义必须相同。但这仅涵盖“类类型(第 9 条)、枚举类型(7.2)、具有外部链接的内联函数(7.1.2)、类模板(第 14 条)、非静态函数模板(14.5.6)、静态数据类模板的成员 (14.5.1.3)、类模板的成员函数 (14.5.1.1) 或未指定某些模板参数的模板特化 (14.7, 14.5.5)”,不是全局变量,此外,定义确实匹配。

我怀疑 [dcl.link] 可能会解决这个问题,但它没有,最接近的是在一个关于具有 C 链接的实体的注释中,它只引用了 [basic.def.odr]:

7.5 联动规范 [dcl.link]

6 [...] [注:程序中只能出现一个具有给定名称的实体的定义和 C 语言链接(见 3.2);这意味着这样的实体不得在多个命名空间范围内定义。--尾注] [...]

我几乎可以肯定我只是忽略了一些东西,因为很明显这是一个错误。

0 投票
1 回答
250 浏览

c++ - 头文件中的内联函数可以使用具有内部链接的常量吗?

考虑以下代码:

假设此代码存在于将包含在多个翻译单元中的头文件中。

我对内联函数的理解是,它们在每个翻译单元中必须完全相同。

我对上面使用的常量的理解是它们是隐式的,static即内部链接。这意味着每个翻译单元都有自己的副本。

由于上面的内联函数依赖于这些常量,这些函数中的哪一个(如果有)是正确的?

0 投票
3 回答
346 浏览

c++ - 在 inline 和 constexpr 函数的情况下,“服从 ODR”是什么意思?

我刚刚读到 constexpr 和 inline 函数遵循单一定义规则,但它们的定义必须相同。所以我尝试一下:

错误:重新定义“void foo()”,
以及

错误:重新定义“constexpr int foo()”

那么究竟是什么意思,constexpr 和 inline 函数可以服从 ODR 呢?

0 投票
1 回答
73 浏览

c++ - 在公共界面和 ODR 中隐藏成员

我在一个库中有多个类,这些类具有我希望对客户端代码隐藏的内部结构。从客户端的角度来看,每个类都是从一个库类中查询出来的,并且只用作一个不透明的指针。一个例子如下:

在实现方面, SomeSystem 有多个调用者不可见的成员。这一切都很好,但我不太喜欢笨拙的用法语法:

另一种方法是:

使用代码:

如果另一种类型也doSomething定义了. 但是,在这种情况下,很难在 IDE 中找到 SomeSystem 的所有“成员”。doSomethingElsedoSomething

我很想实际使用成员函数:

使用代码:

最后一个片段对我来说看起来不错,但 SomeSystem 不再是一个不透明的指针——它实际上定义了成员。我对此有点警惕。一个潜在的问题是单一定义规则。但是,类的“公共”定义和“私有”定义将只对不同的翻译单元可见。这里是否还隐藏着其他不好的东西?如果客户端代码尝试在堆栈上实例化 SomeSystem 或使用 new 它显然会使程序崩溃。但我愿意接受。也许我可以通过在公共接口中提供一个私有构造函数来解决这个问题。

另一种方法当然是用纯虚方法定义一个抽象类。但是,如果不是绝对必要,我想避免这种开销。

编辑:

为了清楚起见,我想知道客户端包含的公共标头包含与实现使用的类的不同定义(缺少一些成员)是否合法,因为客户端从不实例化该类。

公共标头:

私人标头:

私有源(包括私有标头):

这在我测试时有效,但我不确定它是否以某种方式违反标准。这两个标题永远不会包含在同一个翻译单元中。

0 投票
2 回答
545 浏览

c++ - std::make_unique、匿名命名空间和 ODR

请考虑以下测试用例(从 LLVM 源中减少):

这是否违反单一定义规则?

gcc-6 目前是这样认为的:

0 投票
2 回答
79 浏览

c++ - One Definition Rule (ODR) when implementing stack in multiple classes

Can't seem to get a simple stack implementation working. I'm simply trying to get two different classes (class B & class C) to be able to push and print element in the same stack being managed by a third class (class A).

A.cpp

A.h

B.cpp

C.cpp

I think I'm breaking the One Definition Rule. Am I right?