V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Zizpop
V2EX  ›  C++

使用类型转换后为何打印同一个变量会出现两个不同的结果

  •  
  •   Zizpop · 2022-11-30 18:56:58 +08:00 · 1418 次点击
    这是一个创建于 728 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码:

    const char var = 'a';
    auto static_var = static_cast<char>(var);
    auto const_var = const_cast<char*>(&var);
    
    cout << "var: \t\t" << var << "\taddress:\t" << reinterpret_cast<long>(&var) << endl;
    cout << "static_var: \t" << static_var << "\taddress:\t" << reinterpret_cast<long>(&static_var) << endl;
    
    *const_var = 'b';
    
    cout << "const_var: \t" << *const_var << "\tptr:\t\t" << reinterpret_cast<long>(const_var) << endl;
    cout << "var(direct): \t" << var << "\taddress:\t" << reinterpret_cast<long>(&var) << endl;
    cout << "var(ptr): \t" << *(&var) << "\taddress:\t" << reinterpret_cast<long>(&var) << endl;
    

    输出:

    var:            a       address:        6122386111
    static_var:     a       address:        6122386110
    const_var:      b       ptr:            6122386111
    var(direct):    a       address:        6122386111
    var(ptr):       b       address:        6122386111
    

    平台:

    • macbook pro 13 M1
    • macOS 11.6
    • Xcode 13.0
    • Clang 13.0

    请教大家一下, 为何最后两种输出的结果不一样, 这是什么原因导致的

    8 条回复    2022-12-30 12:27:48 +08:00
    lnstrument
        1
    lnstrument  
       2022-11-30 19:12:12 +08:00
    1.编译器认为 var 是常量
    2.const_cast 之后再写可能是 ub

    [Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer
    to data member resulting from a const_cast that casts away a const-qualifier may produce undefined
    behavior (9.2.8.1). — end note]
    nlzy
        2
    nlzy  
       2022-11-30 19:34:00 +08:00
    a) 修改常量对象属于未定义行为
    b) 若程序出现未定义行为,则程序可以做任何(匪夷所思的)事,整个程序失去意义
    smdbh
        3
    smdbh  
       2022-11-30 21:19:52 +08:00
    同意楼上
    Zizpop
        4
    Zizpop  
    OP
       2022-12-01 10:29:20 +08:00
    @lnstrument
    @nlzy
    @smdbh
    谢谢各位的回答. 未定义行为可以在哪查询吗?
    Zizpop
        5
    Zizpop  
    OP
       2022-12-01 10:31:31 +08:00
    @lnstrument
    在条目 1 中意思是程序在汇编中是将’a'直接打印出来而非去查找真正的地址值吗?
    这个注释有来源吗
    cnbatch
        6
    cnbatch  
       2022-12-01 18:01:40 +08:00
    可以查阅 C++标准,1 楼给出的那段文字,位于 ISO IEC 14882 2020-12 的 PDF 的第 126 页。

    国内有转载:
    https://bbs.pediy.com/thread-267401-1.htm
    cnbatch
        7
    cnbatch  
       2022-12-01 18:04:22 +08:00
    对于未定义行为就没必要去纠结了,这种情况下编译器想怎么干都行,甚至直接让整个程序崩溃都不奇怪
    FurryR
        8
    FurryR  
       2022-12-30 12:27:48 +08:00
    会不会是因为在 static_cast 的时候实际上拷贝了一次呢?不过后定义的变量为什么地址比常量低呢?是因为常量默认放在变量后面吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3121 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 00:34 · PVG 08:34 · LAX 16:34 · JFK 19:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.