当前位置:  开发笔记 > 编程语言 > 正文

这个邪恶的演员是否被邪恶的编辑器打败了?

如何解决《这个邪恶的演员是否被邪恶的编辑器打败了?》经验,为你挑选了2个好方法。

这不是学术准则或假设性问题.最初的问题是将代码从HP11转换为HP1123 Itanium.基本上它归结为HP1123 Itanium上的编译错误.在Windows上进行复制时,我真的很抓头.除了最基本的方面之外我已经删除了......如果按原样运行,可能必须按控制D退出控制台窗口:

#include "stdafx.h"
#include 
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) 

谢谢你们!



1> ephemient..:

看起来编译器正在优化

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,所以如果你想要可预测的行为,你根本就不应该这样做.



2> JaredPar..:

常量值IAMCONST被内联到printf调用中.

你正在做的事情充其量是错误的,并且很可能是C++标准未定义的.我的猜测是C++标准让编译器可以自由地内联一个const原语,它是函数声明的本地原语.原因是价值不应该改变.

然后,它是C++应该和可以是非常不同的单词.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有