作者poyenc (发箍)
看板C_and_CPP
标题Re: [问题] constexpr 与 static const 的选择
时间Thu Jun 13 13:33:43 2019
※ 引述《CarbonK (HTYISABUG)》之铭言:
: 开发平台(Platform): (Ex: Win10, Linux, ...)
: Linux
: 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
: GCC
: 问题(Question):
: 对於 constexpr 跟 static const 的差别不太了解
: static const 在编译时期时
: 常数会直接储存在执行档的 .data 这个 segment 里
: 这是我的理解
: 问题是 constexpr 会检查 expression 是否为编译期常数
: 但检查完後它资料是仍然放在 stack 中
: 还是也会放在 .data 中
: 然後我到底该不该用 constexpr 取代 static const ?
: 还是说其实根本可以 static constexpr ?
: 麻烦大家拨冗满足我的好奇心,谢谢
: -----
: Sent from JPTT on my Samsung SM-A810YZ.
它们担任不一样的角色. 先不说後端编译器优化的部分, 先来谈谈
他们各自的分工:
1.
constexpr
要求编译器在编译时期评估 (evaluate) 数值, 或是允许
在评估数值的时候被叫用. 当你现在是
constexpr variable
的情况下,
强制其初始值必须为编译时期可评估的.
2.
static const
在提
static const 之前, 先来讲讲
const.
const 可分
为
使用端和
提供端两个角度来探讨, 前者是指在使用上允
许编译器以值不会改变的前提下做优化; 後者则是提供物
件行为不变的语意. 所以单就
const 来看,
和初始值是不
是编译时期常数完全无关. 加上
static 储存修饰符时,
因为
物件初始时机可能需要提早导致没有太多选项可以用
来当初始值, 才会让你有它跟
constexpr 可以比较的错觉
简单举几个
static const 不为编译时期常数的例子:
1.
static local
const object
https://wandbox.org/permlink/CHGnyam7cH9PVgM1
2.
static global
const object
https://wandbox.org/permlink/vTyRAklJn4AYXBLs
从 1 可以看到: 一旦初始化时机可以不用在 main() 开始前, 就没
必要用编译时期常数来初始化
static const 物件. 从 2 可以看出
: 只要保证不会有 data dependency, 依旧可以在执行时期才求值
初始化.
最後来回答原po的问题, 因为这两者的语意完全不同, 所以选择上
就依照最能表达意图的方式去撰写就可以了.
--
P1389R0: Guidelines for Teaching C++ to Beginners
https://bit.ly/2GvDWKb
SG20 Education and Recommended Videos for Teaching C++
https://www.cjdb.com.au/sg20-and-videos
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 61.216.75.43 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1560404030.A.4C2.html
※ 编辑: poyenc (61.216.75.43 台湾), 06/13/2019 13:37:30
1F:推 CarbonK: 十分感谢你的回文! 06/13 22:06
2F:→ CarbonK: 也就是说,实际上如果要保证编译期常数就应该要用 conste 06/13 22:07
3F:→ CarbonK: xpr 06/13 22:07
4F:→ CarbonK: 而 static const 常常会变成编译期常数是编译器优化的结 06/13 22:08
5F:→ CarbonK: 果 06/13 22:08
6F:→ CarbonK: 我这样的理解是正确的吗? 06/13 22:08
7F:→ poyenc: 你指的如果是不存在於 object file 的话, 对喔 06/14 00:20