问题标签 [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++ - 难以置信的快速 C++ 委托和不同的翻译单元
根据 Sergey Ryazanov 的说法,他的Impossibly Fast C++ Delegates没有可比性:
我的代表无法比较。未定义比较运算符,因为委托不包含指向方法的指针。指向存根函数的指针在不同的编译单元中可能不同。
读者回复了哪一位:
“指向存根函数的指针在不同的编译单元中可能不同。” AFAIK,这不是真的。编译器需要重用在不同编译单元中生成的模板函数(我确信这一点——但我认为 Borland 曾经违反过这条规则)。我认为这是因为类(不在“无名”命名空间中的类)使用外部链接,并且您使用存根函数的方式将始终阻止它们被内联(尽管这不应该成为获取函数地址的问题将强制生成一个非内联版本,并且链接器执行的“外部链接”将消除除一个类似命名的函数之外的所有函数(标准假定并要求它们相同))...
如果您在一个翻译单元(cpp 文件)中定义模板函数,然后在另一个翻译单元中以不同方式定义相同的函数,则只有两个版本中的一个会使其成为最终的可执行文件。(这实际上违反了“一个定义规则”,但适用于 GCC,至少......不确定 MSVC。)关键是:[存根的]地址在不同的单元中是相同的。
如果您发现这对于 MSVC 是正确的,我会敦促您更新文章(包括比较功能) - 如果 MSVC 是标准授予,在这方面。
现在这篇文章已经四年了,作者在过去三年左右没有回复任何评论,所以我想知道上述评论是否有任何优点,是否确实可以将这个具体实现更改为支持对比。
C++ 标准是否明确禁止这种用法,如果是,那么最近的编译器在这方面是否真正符合标准?
c++ - 我什么时候应该为函数/方法编写关键字“内联”?
何时应该inline
在 C++ 中为函数/方法编写关键字?
看到一些答案后,一些相关的问题:
什么时候不应该为 C++ 中的函数/方法编写关键字“内联”?
编译器何时不知道何时将函数/方法“内联”?
当为函数/方法编写“内联”时,应用程序是否是多线程的是否重要?
c++ - 你能解释一下这个 C++ 删除问题吗?
我有以下代码:
WideString 是第三方类,StringUtils 也是如此。它们对我来说是一个黑匣子。第二个参数通过引用传递。
当我逐步通过调试器时,该行return ret
会抛出一个讨厌的弹出窗口(Visual C++),说堆可能已损坏。仔细检查返回的字符串副本是可以的,但删除ret
失败。ret
返回前包含正确的值。
转换功能可能会导致这种情况吗?有什么想法可以解决吗?
更新:
- 项目本身是一个dll
- StringUtils 是一个库
- 项目是针对多线程 CRT 编译的(不是调试,不是 dll)
- 在 Visual Studio 之外运行时,程序似乎运行良好
c++ - 如果它不是纯的,则使用虚拟成员函数?
C++03 3.2.2
...如果对象或非重载函数的名称出现在可能求值的表达式中,则使用该对象或非重载函数。如果它不是纯的,则使用虚拟成员函数...
然后在后面3.2.3
我们有:每个程序都应该包含该程序中使用的每个非内联函数或对象的一个定义;无需诊断。定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。
按照我正在阅读的内容:不使用纯虚函数。ODR 仅适用于使用的功能。这是否意味着以下内容是合法的?我猜答案是否定的,它没有,但我不明白为什么。
c++ - h文件中的静态关键字和内部链接
还有一个static
问题。我已阅读以下内容:
而且我仍然无法理解以下行为:我有一个h
文件:
还有两个cpp
文件:
和:
程序的输出是:
现在,A
的构造函数被调用了两次,因为h
文件被包含了两次,并且由于声明了A
名为的实例,它具有内部链接并且编译器很高兴。由于它也被声明为静态,它也具有内部链接,我希望它的值不会在两个文件中共享 --- 但程序输出暗示该值是共享的,因为它最多为 2。a
static
counter
cpp
有什么见解吗?
h
编辑:在vs.文件中声明静态变量的上下文中,关于什么被认为是“良好的编程习惯”的任何答案cpp
也受到欢迎。
c++ - One Definition Rule: Can corresponding entities have different names?
I read and reread the relevant clauses about ODR in the C++ standard, but this question still remains open to me. The standard says that the definition of an inline function shall appear in every translation unit in which it is used, and the definitions shall be identical in a sense which is described in almost a page. It says the token sequence must be the same. Does it include the local identifier names?
In other words does the following program violate the ODR? (I tried to test it myself with Visual Studio 2008 and got 0 errors and 0 warnings. But I guess this doesn't prove anything, because I then changed the example to two completely different definitions and still got 0 errors and 0 warnings. In excuse of MSVC it should be noted that no diagnostic is formally required for violations of ODR).
c++ - 头文件中的静态变量
静态变量具有文件范围。假设我有以下两个文件:
- 文件1.h
- 文件1.cpp
- 文件2.h
- 文件2.cpp
我已经static int Var1
在两个头文件中声明了静态变量。两者file1.h
都file2.h
包含在main.cpp
文件中。
我这样做是因为静态变量将具有文件范围,因此不会相互冲突。但编译后我发现它显示冲突。
现在静态变量的行为就像一个extern
变量。另一方面,如果我在两个 .cpp 文件中声明静态变量,它编译得很好。
我无法理解这种行为。
任何机构都可以解释范围和链接在这种情况下是如何工作的。
c++ - 在其 .h 文件包含在多个 cpp 文件中的类中定义整数静态常量
编译器向我发出警告,说 b 被定义了多次,其中一个被忽略了。我需要在类中定义它,因为我需要初始化数组。或者,我需要使用枚举方法来做到这一点。但我想知道这是否可能?
c++ - 谁能解释当前 C++0x 标准草案的这一段?
谁能从 ISO N3242 §3.2 第 2 点解释这个声明
如果在从潜在评估的表达式中引用时通过重载决策选择了一组候选函数的成员,则该成员是 odr-used 的。[注意:这包括对命名函数的调用(5.2.2)、运算符重载(第 13 条)、用户定义的转换(12.3.2)、用于放置新的分配函数(5.3.4)以及非默认初始化(8.5)。
ISO标准2003:说
如果在从潜在评估的表达式中引用时通过重载决议选择了重载函数,则使用重载函数。[注意:这包括对命名函数的调用(5.2.2)、运算符重载(第 13 条)、用户定义的转换(12.3.2)、用于放置 new 的分配函数(5.3.4)以及非默认初始化(8.5)。
这些陈述的实际区别是什么?
任何人都可以借助示例/程序来解释这一点吗?