gpt4 book ai didi

c++ - 邪恶的 Actor 会被邪恶的编译器击败吗?

转载 作者:可可西里 更新时间:2023-11-01 18:02:17 25 4
gpt4 key购买 nike

这不是学术代码或假设性问题。最初的问题是将代码从 HP11 转换为 HP1123 Itanium。基本上归结为 HP1123 Itanium 上的编译错误。在 Windows 上复制它进行研究时,我真的很抓狂。除了最基本的方面,我已经删除了所有内容...如果按原样运行,您可能必须按 control 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;
}

这是输出

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 的地址,它实际上必须位于堆栈中的某处,并且不能强制执行 constness,所以该位置的内存 (*pTOCONST) 毕竟是可变的。

简而言之:您抛弃了 constness,不要那样做。可怜的,手无寸铁的 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 规范 allows C 编译器假设任何 int * 指针的目标永远不会与 const int 的内存位置重叠,所以如果你真的不应该这样做想要可预测的行为。

关于c++ - 邪恶的 Actor 会被邪恶的编译器击败吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/712334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com