这不是学术准则或假设性问题.最初的问题是将代码从HP11转换为HP1123 Itanium.基本上它归结为HP1123 Itanium上的编译错误.在Windows上进行复制时,我真的很抓头.除了最基本的方面之外我已经删除了......如果按原样运行,可能必须按控制D退出控制台窗口:
#include "stdafx.h"
#include <iostream>
using 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;
}
Run Code Online (Sandbox Code Playgroud)
这是输出
IAMCONST 3
WHATISPOINTEDAT 7
Address of IAMCONST 35f9f0 pTOCONST 35f9f0
Run Code Online (Sandbox Code Playgroud)
我只能说是什么?这样做是不明确的?对于这样一个简单的例子,这是我见过的最违反直觉的事情.
更新:
确实在搜索了一段时间后,菜单调试>> 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)
Run Code Online (Sandbox Code Playgroud)
谢谢你们!
eph*_*ent 24
看起来编译器正在优化
printf("IAMCONST %d \n",IAMCONST);
Run Code Online (Sandbox Code Playgroud)
成
printf("IAMCONST %d \n",3);
Run Code Online (Sandbox Code Playgroud)
既然你说那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
Run Code Online (Sandbox Code Playgroud)
从*(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
Run Code Online (Sandbox Code Playgroud)
你可以清楚地看到使用常数3代替.
如果您使用的是Visual Studio CL.EXE,请/Od禁用优化.这因编译器而异.
请注意,C规范允许 C编译器假设任何int *指针的目标都不会与a的内存位置重叠const int,所以如果你想要可预测的行为,你根本就不应该这样做.
常量值IAMCONST被内联到printf调用中.
你正在做的事情充其量是错误的,并且很可能是C++标准未定义的.我的猜测是C++标准让编译器可以自由地内联一个const原语,它是函数声明的本地原语.原因是价值不应该改变.
然后,它是C++应该和可以是非常不同的单词.
| 归档时间: |
|
| 查看次数: |
926 次 |
| 最近记录: |