问题标签 [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 投票
1 回答
701 浏览

c++ - 单一定义规则是否强制创建单个静态函数变量?

例如,考虑以下标头:

如果我有两个不同的 C++ 文件,包括这个文件——它会打印两次相同的地址吗,保证?更重要的是,如果x是具有非平凡构造函数的不同类型的对象,是否可以保证只运行一次?

0 投票
3 回答
4313 浏览

c - 全局变量与局部变量的重新声明

当我编译下面的代码时

我收到一个错误:

但是,如果我将变量设为全局变量,则它可以正常工作。

为什么两次声明同一个全局变量不是错误,但对局部变量这样做是错误的?

0 投票
1 回答
91 浏览

c++ - 链接到链接到我已经链接到的库的库

原谅复杂的标题。

此问题的设置如下:

我有一个开源库,我已经内置到一堆 .libs 中(如果你好奇的话,VTK)

我有一个使用上述静态库的库。让我们称之为 Lib A。

我还有一个使用上述库(即 VTK)并且还使用 Lib A 的应用程序。

在构建期间,我收到一个链接器错误,告诉我从 Lib A 调用的函数已在链接到应用程序的库中定义(错误:LNK2005)

关于如何解决将所有内容切换为动态链接的任何想法?

0 投票
1 回答
1124 浏览

c++ - 通过通用引用传递静态 constexpr 变量?

在下文中,static constexpr成员L在类中初始化,A然后通过值或(通用)引用传递。后者在 Clang 中失败,但在 GCC 中失败,并且成员/非成员函数的行为略有不同。更详细地说:

在将问题从更大的程序中分离出来的一些实验之后,我意识到我不小心使用了constexpr变量的地址,尽管我只对值感兴趣。

我想通过(通用)引用,以便代码是通用的,并且可以在不复制的情况下使用大型结构。我认为您可以通过通用参考传递任何内容,但这里的情况似乎并非如此。我不能使用单独的(类外)定义,L因为这是仅标头库的一部分。

因此,一种解决方法可以是在调用时生成一个值,即说size_t(A::L)或类似的东西A::get_L()而不是 just A::L, where (within class A)

但是这两种解决方案看起来都有些笨拙。在我的实际代码中,调用是在类中进行的,看起来call(0, L, ...)很无辜(0, L看起来像值)。我想让通话尽可能简单。

我认为这个问题及其后续几乎可以解释正在发生的事情。那么任何人都可以建议最干净的方法来处理这个问题吗?

0 投票
1 回答
442 浏览

c++ - 指向函数和 ODR 的指针

关于 ODR 有很多问题,但我找不到我要找的东西,所以如果这是重复的或标题不合适,我们深表歉意。

考虑以下:

这是对我为每种类型定义唯一标识符的尝试的过度简化,希望它在不同的编译单元中保持唯一。

特别是,给定一个具体的类型Tstd::string假设两个不同的编译单元在头文件中包含上述代码,我想表达

在两个单元中采用相同的值(类型t(*)()),因此用作类型的唯一标识符T

该值是函数的地址type<T>,所以问题是程序type<T>中的唯一函数是否由单定义规则保证。iso 3.2/3 说

每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义。

3.2/2 在哪里

名称显示为潜在求值表达式或 [...] 的非重载函数是 odr 使用的,除非 [...]

如果一个函数的地址被占用,我假设它是非内联的(尽管我在标准中找不到它)。

iso 3.2/5 列出了一些例外,但对函数的唯一引用是

具有外部链接的内联函数、[...]、非静态函数模板、[...]、类模板的成员函数或未指定某些模板参数的模板特化 [...]

而且这里似乎没有。

一个可验证的示例需要多个文件。事实上,Dieter Lücking给出了一个声称失败的例子,尽管在我的情况下它并没有失败(我不认为这是任何形式的“保证”)。

那么,这会奏效吗?

0 投票
1 回答
2670 浏览

c++ - 何时在 C++14 中使用变量 odr?

C++14 草案 (N3936) 在 §3.2/3 中指出:

变量 x 的名称显示为潜在求值表达式 ex 是 odr-used 除非将左值到右值转换 (4.1) 应用到 x 产生不调用任何非平凡函数的常量表达式 (5.19),并且,如果x 是一个对象,ex 是表达式 e 的潜在结果集合中的一个元素,其中左值到右值的转换(4.1)应用于 e,或者 e 是丢弃值表达式(第 5 条)。

这对我来说没有任何意义:如果表达式e丢弃值表达式取决于使用的上下文e表达式语句(第 6.2 节)中使用的每个表达式都是废弃值表达式。是否应用左值到右值转换e也取决于使用的上下文e

此外,一个表达式位于另一个表达式的潜在结果集中意味着什么。一个人需要一个表达式相等的概念才能确定一个集合的成员。但是我们没有参考透明度,所以我看不出这是如何实现的。

为什么从 C++11 更改为 C++14?这应该如何解释?就目前而言,这没有意义。

0 投票
1 回答
319 浏览

c++ - 这句话在 C++11 标准的第 3.2/2 段中是什么意思?

该句子是第 3.2/2 段的一部分:

名称显示为潜在求值表达式的变量是 odr-used 的,除非它是一个满足出现在常量表达式 (5.19) 中的要求并且立即应用左值到右值转换 (4.1) 的对象

上面加粗的句子到底是什么意思?

编辑

这个被认为是重复的问题的答案并没有说任何可以回答我的问题的东西。

0 投票
4 回答
1797 浏览

c++ - c++ 中的一种定义规则

根据 c++ 标准:

任何翻译单元都不得包含一个以上的任何变量、函数、类类型、枚举类型或模板的定义。

你能解释一下 ODR 是如何工作的吗?

0 投票
2 回答
1253 浏览

c++ - 在标头中使用未命名的命名空间会如何导致 ODR 违规?

在 Google C++ Style Guide 中,命名空间部分指出“在头文件中使用未命名的命名空间很容易导致违反 C++ 单一定义规则 (ODR)。

我明白为什么不在实现文件中使用未命名的命名空间会导致 ODR 违规,但不知道在标头中使用如何做到这一点。这怎么会导致违规?

0 投票
5 回答
5163 浏览

c++ - “重新定义”是什么意思?

重新定义是否意味着我们正在尝试定义一个已经定义的实体。这个问题出现在以下代码示例中:

还有一个例子:

我们不能foo()main()函数体内定义刚刚声明的函数,但如果可以的话,它会是一个重新定义吗?