作者LPH66 (IS YOU)
看板C_and_CPP
标题Re: [问题] const 变数在.h, undefined behavior?
时间Thu Jul 25 18:21:11 2019
我回文整理一下好了, 推文好像会越推越长
※ 引述《lovejomi (JOMI)》之铭言:
: https://www.fluentcpp.com/2019/07/23/how-to-define-a-global-constant-in-cpp/
: 偶然看到这篇,我其实觉得他写错
: 这部分
: Each file has its own version of焏. This is a problem for three reasons:
: it is undefined behaviour (objects must be defined only once in C++),
: ??????真的undefined吗?有没有什麽表格或网址整理ub...之前看到说把东西写在
: namespace std也是ub...也太多很容易就写出来的ub了吧
一个很令人沮丧的事实是 C++ 确实很多很容易写出来的 UB...
: it uses more memory,
: if the constructor (or destructor) of曱温as side effects, they will be execute
: d twice.
: 这句看不懂,什麽是side effect在这里?
: 他的范例我唯一能看出问题的就是你没办法保证cout比他的x先初始化
: 其他他说执行两次cstor不是很正常吗?
1F:推 LPH66: 执行两次 ctor 正是他的第三点在说的07/25 17:44
2F:→ LPH66: 你以为只有一个全域变数其实有两个07/25 17:45
3F:→ LPH66: 其证据即是建构子被执行了两次07/25 17:45
4F:→ LPH66: 那在同一支程式里有两个同名字的不同全域变数即是 UB 了 07/25 17:48
5F:→ LPH66: 这是明确违反 one-definition rule 的 UB07/25 17:49
One Definition Rule (ODR) 是 C++ 里的一个很重要的概念
重要到标准里有一个衍生词叫做 "odr-used" 来形容一个东西
被如此形容的东西在整支程式的所有转译单元当中有且仅能有恰好一个定义
: 我只记得const自带static,所以预设是internal linkage
: https://en.cppreference.com/w/cpp/language/cv
: 的Note也是这样写
: 但他说是ub 我觉得很奇怪…..
不过下面的回应好像有跟你一样的问题:
qsvui ‧ 2 days ago
I'm not sure that your very first example of putting a const variable in the
header is undefined behavior.
他举了跟你提到的同样的段落表示怪怪的
: 最後他提到inline,
: inline跟extern效果一样,意思是c++鼓励使用inline而不是extern吗
: 谢谢
6F:→ LPH66: 後半篇文章的 inline (C++17) 和 extern (pre-C++17)07/25 17:50
7F:→ LPH66: 它们的作用并不一样: "It looks somewhat similar to07/25 17:51
8F:→ LPH66: inline, but its effect is very different."07/25 17:51
文中很明确的跟你说了:
With extern, the above code is a
declaration, and not a definition. With
inline, it was a definition.
extern 只做宣告不做定义, 所以可以在各个不同转译单元当中同时存在
但是若它被 odr-used 那你就必须给它一个定义
因此你必须在其中一个转译单元中定义它
C++17 的 inline 变数跟以前的 inline 函数的概念颇像 (或者该说就是这样延伸来的)
它能够有多於一个定义, 只要大家的定义完全相同即可
所以在 C++17 我们可以像贴 inline 函数一样为全域变数贴 inline
编译器就知道这些在各个转译单元中宣告 inline 的变数是同一个东西而把它整合在一起
而由於这已经是个定义, 因此就无须特别在其中一个转译单元中定义之了
(反而这里再多定义就违反 inline 的完全相同的约定, 那这就又是 UB 了)
--
有人喜欢边
玩游戏边
上逼;
也有人喜欢边
听歌边
打字。
但是,我有个请求,
选字的时候请
专心好吗?
-- 改编自「古 火田 任三郎」之开场白
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.177.3.123 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1564050073.A.CDC.html
9F:推 kyushu: 推 07/25 18:49
10F:推 lovejomi: 所以好像是不是ub也不明确,但我们常常在cpp 写一些cons 07/26 11:43
11F:推 lovejomi: 在global, 只要两个cpp都不小心这样写撞名 难道就ub?这 07/26 12:02
12F:→ lovejomi: 样要怎麽写code... 07/26 12:02
13F:推 sarafciel: 1.你可以写个singleton统一管理全域物件 07/26 17:39
14F:→ sarafciel: 2.不喜欢singleton,还可以拿个namespace包起来防撞名 07/26 17:40
15F:→ sarafciel: 3.你其实没那麽需要让大家都爽爽看的全域变数,不是贪 07/26 17:43
16F:→ sarafciel: 图方便,就是对scope跟权责的控制没有观念 07/26 17:45
17F:推 sarafciel: 如果是後者,比起研究那些是UB然後不要踩雷,花时间去 07/26 17:52
18F:→ sarafciel: 学这些设计原则才是真的 07/26 17:53
19F:推 lovejomi: 可是你明明知道 const int 是internal linkage 你不该会 07/27 09:49
20F:→ lovejomi: 想摆在无名namespace吧? 多多少少写cpp会想named magic 07/27 09:49
21F:→ lovejomi: number in global啊 撇除constexpr 07/27 09:49
其实说到 linkage
我在想会不会这种习惯/误解有可能是因为在 C 语言这个是 external linkage 有关
同样引用你举过的那个地方:
> ... This is different from C where const file scope variables have external
> linkage.
在 C 的时代已经这样理解/这样被教导所以到了 C++ 照样带了进来这样
不说别的, 我自己在仔细找过资料之前也有差不多的误解...
※ 编辑: LPH66 (180.177.3.123 台湾), 07/27/2019 12:49:42