问题标签 [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.
c++ - 为什么获取内联定义的静态 const 整数成员变量的地址不会违反 ODR?
如果它编译,这样的事情将明显违反 C++ 单一定义规则:
因为如果 something.h 包含在多个模块中,A::val
则会重复定义。但是,这是允许的:
据我了解,这种情况可以的原因是因为B::val
它是一个整数类型的编译时常量,所以编译器基本上可以B::val
用文字对所有引用进行搜索和替换3
(反汇编的检查表明了这一点正是它的作用)。因此,在某种意义上,最终产品中的定义为零B::val
,因此 ODR 不适用。但是,考虑一下:
这是允许的,反汇编表明在这种情况下,实际上已经预留了一些内存位置来存储 的值C::val
。从表面上看,这意味着如果 yetAnotherThing.h 包含在多个模块中,我们现在就违反了 ODR,因为static const int val = 3
现在会导致存储被“发射”。然而编译器和链接器(VC++2012)都没有抱怨。
为什么?这只是编译器/链接器的作者必须处理的令人讨厌的特殊情况吗?如果是这样,为什么不能使用相同的系统来使案例 #1 也可以工作?
(欢迎引用标准中的相关引用,但它们不一定能回答问题。如果标准说pink_elephants
关键字的任何使用都应该导致数字 42 的每个实例都被替换为 666,那么就是这样,但我们'仍然会想知道为什么存在这样一个奇怪的规则。)
c++ - GoogleTest PrintTo 没有被要求上课
我有一个相当奇怪的问题,告诉 googletest 使用 PrintTo 以我想要的方式打印某个类。
该类是一个非常简单的 2D 点,它位于命名空间中,而 PrintTo 函数位于同一命名空间中。事实上,我有一个可以完美打印的派生类(一个 3D 点)。
这是测试和 PrintTo 函数的一些代码(命名空间名称已编辑,但其他所有内容都是从实际代码中复制和粘贴的):
我试图在一个简单的测试项目中复制这个问题,但它打印得很完美。我能想到的测试项目和真实项目之间的唯一区别是,在真实项目中,CPunto2D 和 CPunto3D 类位于 dll 中,当然还有更多类,它们依赖于库。
关于为什么不选择 PrintTo 函数的任何想法?
我正在使用 Visual Studio 2008 和 googletest 1.7
注意:尽管示例使用了 GMock 的 ASSERT_THAT,但我已经使用 ASSERT_EQ 进行了尝试,结果是一样的。
更新:
以下是 CUnto2D 和 CUnto3D 的声明。CLAS_DEC 只是一个用于从 dll 导入/导出的宏。我知道这些课程有大约一百万个问题,比如公共成员等,所以如果它与手头的问题无关,请不要指出这些问题。
c++ - 为什么将内联函数def放在其他头文件中,其中包含内联函数声明的头文件是链接错误?
我有两个标题。
我在 MSVC 2013 上遇到链接错误。我只有一个翻译单元,所以我认为也许“ODR”不是原因?
现在我有 test2.cpp 来包含 header2.h。所以我认为链接器现在可以找到 header2.h 。但是还是链接错误,为什么?
c++11 - 在没有类外定义的情况下访问静态 constexpr std::array
我有一个定义一些数组的类。
点数.hpp
然后我的主文件使用这些数组。
主文件
当我使用 C++11 和 g++ 4.8.2 编译我的代码时,我收到以下链接器错误:
我试图创建一个 Points.cpp 文件,以便编译器可以从中创建一个目标文件。
点数.cpp
但这并没有解决链接器错误。
我的印象是可以在类声明中将变量初始化为 C++11 中的静态 constexpr,然后按照我的方式访问它们,如以下问题所示:https ://stackoverflow.com /a/24527701/1991500
我是否需要为 Points 创建一个构造函数,然后实例化该类?我究竟做错了什么?
任何反馈表示赞赏!谢谢!
c++ - 在头文件中使用`const char thing[] = "foo";`?
我想创建一个常量全局字符数组,这样
- 它可以在多个翻译单元中使用。
- 数组的长度是从用于初始化它的字符串文字推导出来的。
- 该字符串文字在我的源文件中仅存在一次(如果可能,在目标文件中)。
- 其中所有的翻译单元都有编译时访问的长度。
- 当多个翻译单元链接在一起时,没有 ODR 违规。
从理论上讲,这应该可以通过使用const char[]
减速/定义并将其放入头文件中,以强制数据/符号进入 COMDAT 部分,但我不知道标准(甚至任何编译器)是否支持。
ps 假设使用的任何习语都将用于许多文件中的数百到数千个常量。
编辑:我所知道的给出所有要点的“最干净”的解决方案是:
这仍然是相当丑陋的。
OTOH 如果我只是扔掉 3b (保证相同的存储模块内联),那么这项工作:
因为默认情况下它具有内部链接。一个好的链接器可以合并这些,但此时你不能说地址/标识符的相等性之间的关系(即不要将其转换为指针并将其用作标识)。但这是一个警告,可能几乎一直都是良性的。
c++ - C ++ - 在模板类之外但在标题中定义成员函数
我已经定义了一个带有一个成员函数的简单类模板。它是在类外定义的,具有额外的(显式)特化,也在类外定义。全部在一个头文件中。如果您在多个翻译单元中包含此标头,则会由于 One-Definition-Rule 导致链接器错误。
到目前为止一切都很好。但是如果我将成员函数的定义放在类体内,链接器错误就会消失,并且这些函数可以在不同的翻译单元中使用。
我的问题是为什么它会这样工作?我使用 MSVC 2012。ODR 在模板上有一些例外,我最初认为这是原因。但是类内部/外部的“Base”函数的定义在这里有所不同。
c++ - 不同的函数有不同的地址吗?
考虑这两个函数:
可以保证&foo != &bar
吗?
相似地,
可以保证&foo<int> != &foo<double>
吗?
我知道有两个链接器将函数定义放在一起。
MSVC 积极地 COMDAT 折叠函数,因此具有相同实现的两个函数可以变成一个函数。作为副作用,这两个函数共享相同的地址。我的印象是这是非法的,但我无法在标准中找到它是非法的。
Gold 链接器还折叠函数,包括 asafe
和all
设置。 safe
意思是如果一个函数地址被取了,它不会被折叠,而all
即使地址被取了也会折叠。所以黄金的折叠safe
表现得好像函数有不同的地址。
虽然折叠可能是出乎意料的,并且有些代码依赖于具有不同地址的不同(相同实现)函数(因此折叠可能很危险),但在当前的 C++ 标准下它实际上是非法的吗?(此时为 C++14)(自然好像safe
折叠是合法的)
c++ - 内联函数体的潜在评估和模板成员的实例化
何时将标记为 inline 的函数中包含的表达式视为“可能已评估”?
a.cpp
b.cpp
如果定义内联函数后立即将表达式视为“可能评估”,则应实例化模板,并且我希望$(CCC) -c a.cpp; $(CCC) -c b.cpp; $(CCC) a.o b.o -o bin
链接成功。相反,如果声明为 inline 的函数中的表达式仅在此类函数本身变为 odr-used 时才变为“潜在评估”,那么我预计$(CCC) -c a.cpp; $(CCC) -c b.cpp; $(CCC) a.o b.o -o bin
在链接步骤期间会失败。
到目前为止,我已经测试了 xl C++ 12(链接成功)和各种版本的 gcc + clang 3.5(所有这些都无法链接)。
哪种行为是正确的?我在这里错过了第三种选择吗?
python - 使用 scipy.ODR 的线性回归失败(解决方案中的排名不全)
尝试使用 scipy.odr 进行线性回归也是如此。然而,它惨遭失败。scipy.odr 以前为我工作过,我没有在我的代码中看到任何错误。我能想到的唯一原因是斜率可能太小,但我不明白这会如何打扰 scipy。谢谢您的帮助。
编码:
这是最终的终端输出:
这是生成的图形:
编辑:我的 odr 回归代码来自http://docs.scipy.org/doc/scipy/reference/odr.html