-
Notifications
You must be signed in to change notification settings - Fork 8.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于 const 与常量的关系存在的错误与遗漏 #5
Comments
+1 |
感谢指出!文中已修正~ |
感谢~ |
借楼发个词语订正: 显示 -> 显式 最后一段
|
感谢,已修订~ |
我丢,没看懂,反而更晕了 |
请问,这里讨论的“常量表达式”是指 如果是的话,那按照我的理解,常量表达式完全不局限于整数和枚举,浮点也没问题,甚至自己定义一个类都可以(只要满足一定的要求)。标准库中一些类(例如 |
其实常量表达式和 |
考虑如下代码: const float a = 1.0;
constexpr float b = a;
constexpr float b = 1.23; 或 constexpr float a = 1.23;
constexpr float b = a; |
#define 为啥会多份内存copy啊,预处理阶段进行文本替换。就看替换之后的内容存放的位置,如果立即数替换,没有拷贝的地方,如果是函数替换也没有多份内存拷贝的地方,用得还是原来的东西呀。。 |
已删 |
2022年7月23日:github网页上的效果,对此处更改时使用的 |
可是,好像实验下来,const int a = 1; constexpr int b = a; 这个是可以编过的,而int换成float就会提示b不是用常量表达式初始化 |
确实,我的错 |
define定义的常量在内存中有若干个拷贝怎么理解啊 |
应该是define定义的常量以立即数的形式存储在指令中,当有一条指令需要使用常量的时候就会对其有一份拷贝,而指令是存储与内存中的 |
如何理解这句话?我记得以前看过的内容说#define定义的宏在预处理阶段就替换掉了,运行过程中怎么会出现内存里有若干个拷贝呢 |
学了汇编就知道了。常量是立即数,没有内存地址,是指令的一部分,使用的时候直接使用值,所以是不可访问的,在预编译阶段就确定了,变量是有内存地址的,使用的时候直接用变量名或者地址就行了。还有,const定义的变量如果改变的话在编译器阶段就无法通过,这是和普通变量的区别,使用的时候都是用地址访问值,所以也不存在多份拷贝 |
页面链接
此处的错误在于
#define
定义的宏常量(假设它不是花括号初始化器列表)同样存在类型。例如若写
#define FOURTY_TWO 42
,则FOURTY_TWO
的类型是int
。具体的类型和各种字面量(整数、浮点、用户定义等)和运算符的结果类型有关。此处的错误在于,若用
const
定义常量(类型为整数或枚举,必须以常量表达式初始化),则这种常量在非 odr 式使用(粗略来说是只使用其值)时不需要依赖其身为变量的身份,一定场合下甚至可以不需要定义(譬如作为类的static
成员对象)。编译器在作为常量处理它时,不会依赖“一份定义”,而是像是立即数一样使用它,它本身可能在机器码中被“拷贝”到多个地方,和
#define
定义的宏常量的结果相同。另一方面,
const
定义的常量由于是整数或枚举,所以直接变成机器码上的立即数往往性能更好。最后是遗漏的一点:
const
定义的变量只有类型为整数或枚举,且以常量表达式初始化时才能作为常量表达式。其他情况下它只是一个const
限定的变量,不要将与常量混淆。The text was updated successfully, but these errors were encountered: