这不是学术准则或假设性问题.最初的问题是将代码从HP11转换为HP1123 Itanium.基本上它归结为HP1123 Itanium上的编译错误.在Windows上进行复制时,我真的很抓头.除了最基本的方面之外我已经删除了......如果按原样运行,可能必须按控制D退出控制台窗口:
#include "stdafx.h" #includeusing namespace std; int _tmain(int argc, _TCHAR* argv[]) { char blah[6]; const int IAMCONST = 3; int *pTOCONST; pTOCONST = (int *) &IAMCONST; (*pTOCONST) = 7; printf("IAMCONST %d \n",IAMCONST); printf("WHATISPOINTEDAT %d \n",(*pTOCONST)); printf("Address of IAMCONST %x pTOCONST %x\n",&IAMCONST, (pTOCONST)); cin >> blah; return 0; }
这是输出
IAMCONST 3 WHATISPOINTEDAT 7 Address of IAMCONST 35f9f0 pTOCONST 35f9f0
我只能说是什么?这样做是不明确的?对于这样一个简单的例子,这是我见过的最违反直觉的事情.
更新:
确实在搜索了一段时间后,菜单调试>> Windows >>反汇编完全具有下面描述的优化.
printf("IAMCONST %d \n",IAMCONST); 0024360E mov esi,esp 00243610 push 3 00243612 push offset string "IAMCONST %d \n" (2458D0h) 00243617 call dword ptr [__imp__printf (248338h)] 0024361D add esp,8 00243620 cmp esi,esp 00243622 call @ILT+325(__RTC_CheckEsp) (24114Ah)
谢谢你们!
看起来编译器正在优化
printf("IAMCONST %d \n",IAMCONST);
成
printf("IAMCONST %d \n",3);
既然你说那IAMCONST
是一个const int
.
但是因为你要获取地址IAMCONST
,所以它必须实际位于堆栈的某个地方,并且const
不能强制执行,因此该位置(*pTOCONST
)的内存毕竟是可变的.
简而言之:你已经离开了const
,不要这样做.穷人,手无寸铁的C ......
使用GCC for x86,使用-O0
(无优化)生成的程序集
main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $36, %esp movl $3, -12(%ebp) leal -12(%ebp), %eax movl %eax, -8(%ebp) movl -8(%ebp), %eax movl $7, (%eax) movl -12(%ebp), %eax movl %eax, 4(%esp) movl $.LC0, (%esp) call printf movl -8(%ebp), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $.LC1, (%esp) call printf
从*(bp-12)
堆栈复制到printf
参数.然而,使用-O1
(以及-Os
,-O2
,-O3
,和其他优化级别),
main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $20, %esp movl $3, 4(%esp) movl $.LC0, (%esp) call printf movl $7, 4(%esp) movl $.LC1, (%esp) call printf
你可以清楚地看到使用常数3
代替.
如果您使用的是Visual Studio CL.EXE
,请/Od
禁用优化.这因编译器而异.
请注意,C规范允许 C编译器假设任何int *
指针的目标都不会与a的内存位置重叠const int
,所以如果你想要可预测的行为,你根本就不应该这样做.
常量值IAMCONST被内联到printf调用中.
你正在做的事情充其量是错误的,并且很可能是C++标准未定义的.我的猜测是C++标准让编译器可以自由地内联一个const原语,它是函数声明的本地原语.原因是价值不应该改变.
然后,它是C++应该和可以是非常不同的单词.