使用地址解释强制转换const
C++ - Casting const by using the address explanation
我用c++写了下面的代码:
我想对const变量进行类型转换,然后改变它,这是代码:
#include <iostream>
using namespace std;
int main()
{
int const a = 5;
int* ptr = (int*)&a;
*ptr = 10;
cout<<"a is : "<< a << endl;
system("pause");
}
这段代码通过了编译器,我希望程序能打印在屏幕上10,
但是屏幕显示的结果是5。
当我运行调试器时,&a中的内存已经像我预期的那样更改为10。
知道为什么吗?
首先这是未定义行为。不要这样做。其次,当您打印出a
时,编译器实际上在查看&a
的内存,因为您告诉编译器a
永远不会改变(您说它是const
)。所以它实际上变成了…
cout << "a is : "<<5 << endl;
你正在调用未定义的行为与问题的代码,试图改变一个变量声明为const
的cast away constness是不允许的(除非const变量真的是一个变量不是const
的引用)。
对您的结果的一个合理且极有可能的解释是,编译器知道a
的值不应该改变,因此它几乎可以将a
的所有出现替换为5
。ie。"查找"被优化掉了。
为什么要查看a
的地址来读取它的值,当它被声明为始终是5
时?
让我们看一下编译器可能将代码段转换成的指令
foo.cpp
void func (int)
{
/* ... */
}
int
main (int argc, char *argv[])
{
const int a = 10;
int * p = &const_cast<int&> (a);
*p = 20;
func (a);
}
<一口>一口>
main
的汇编指令由g++ -S foo.cpp
给出
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $10, -12(%rbp)
leaq -12(%rbp), %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax # store the adress of `a` in %rax
movl $20, (%rax) # store 20 at the location pointed to by %rax (ie. &a)
movl $10, %edi # put 10 in register %edi (placeholder for first argument to function)
# # notice how the value is not read from `a`
# # but is a constant
call _Z4funci # call `func`
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
如上所示,20
的值确实被放在%rax
中存储的地址,其中(%rax)
包含a
(movl $20, (%rax)
)的地址,但是我们调用void func (int)
的参数是常数10
(movl $10, %edi
)。
如前所述;编译器假定a
的值不会改变,而不是每次使用a
时都读取内存位置,而是将其替换为常量值10
。
相关文章:
- 为什么这个函数将"const char*"转换为"void* const"而不是"const void*"
- 'HMODULE LoadLibraryA(LPCSTR)':无法将参数 1 从 'const _Elem *' 转换为 'LPCSTR'
- 将函数参数"const char*"转换为"std::string_view"是
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 启用从"vector<const T>&"到"const vector&"的隐式转换<T>
- 将 const 转换为 const char* 无效,我该如何解决?使用 gcc7 时失败
- C++ TCP 套接字 | 无法将"std::__cxx11::字符串"转换为"const
- C++ 无法从 const int* 转换为 const_iterator
- 为什么我的编译器在调用 const getter 函数时抛出"转换丢失(const)限定符"错误?
- 如何在 c++ 中将向量转换为<string>常量字符* const*?
- 无法从'const std::string [3]'转换为'std::string'
- 无法在返回中转换 const 对象
- Tensorflow Lite ARM64错误:无法转换‘const int8x8_t
- 一种体面的方式来转换const列表参考参数,然后传递到另一个函数
- Overloading STD :: Whow()无法转换const char*
- 使用工厂方法时编译器错误:无法转换"const std::p air<char* const
- 强制转换 const 指针以使用旧版 C 代码
- 使用地址解释强制转换const
- c++转换const引用传递
- c#可以强制转换const吗?