【问题标题】:const char* to int cast?const char* 到 int 转换?
【发布时间】:2023-03-08 11:19:01
【问题描述】:

我认为以下 sn-p 的行为应该是未定义的,但我只是想确保我理解正确。 假设我们有这段代码:

#include <iostream>

int main()
{
  std::cout << "mamut" - 8 << std::endl;
  return 0;
}

所以我认为它的作用是 (char*)((int)(const char*) - (int)),尽管之后的输出很奇怪,但我并不希望它有任何实际意义。所以我的问题是关于 char* 和 int 之间的转换 - 它是未定义的,还是背后有一些逻辑?

编辑: 让我补充一下:

#include <iostream>

int main ()
{
    const char* a = "mamut";
    int b = int(a);
    std::cout << b << std::endl;
    std::cout << &a <<std::endl;
    // seems b!= &a
    for( int i = 0; i<100;i++)
    {
        std::cout<<(const char*)((int)a - i)<<std::endl;
    }

    return 0;
 }

我变得足够大后的输出给了我一个类似 _Jv_RegisterClasses 等的东西。 仅作记录:

std::cout << a - i << std::endl;

产生与以下相同的结果:

std::cout<<(const char*)((int)a - i)<<std::endl;

【问题讨论】:

  • 这是未定义的行为,但不是因为您认为的原因。谷歌指针算法。
  • 当您减去8 时,您似乎假设const char* 被转换为int。假设是错误的。
  • 为什么假设是错误的?我的意思是你不能添加 char*,因为 + 没有为 char* + char* 定义。
  • 您的编辑也与原始问题无关。请在每个帖子中只问一个问题,如果您有不同的问题,请发布新帖子。
  • 编辑几乎是同一个程序,但随着 i 变大(基本上你会看到除 "mamut" - 8 之外的其他结果)。我为每个 i 制定了循环原因,它打印出我正在谈论的输出。

标签: c++ casting char int


【解决方案1】:

没有强制转换,您只是告诉 cout 您要在字符串文字“mamut”的地址减去 8 个字节打印字符串。你正在做指针算术。然后 cout 将打印该地址处发生的任何内容,或者可能会崩溃和烧毁,因为越界访问数组会导致未定义的行为。

编辑

关于操作员的编辑:将地址转换为int 不一定会产生与地址相同的正确数字。地址不一定适合int,除此之外,int 是有符号类型,将地址存储在有符号类型中没有任何意义。

为了保证从指针到整数的转换没有损失,您需要使用 stdint.h 中的uintptr_t

引用 C 标准 6.3.2.3(我相信 C++ 在这种情况下是相同的):

任何指针类型都可以转换为整数类型。除了作为 之前指定的,结果是实现定义的。如果 结果不能用整数类型表示,行为是 不明确的。结果不必在任何值的范围内 整数类型。

【讨论】:

  • 问题是 (int)a 没有给我 a 的地址。基本上 &a != (int)a。从一开始我的问题就是 (int)a 给了我什么。
  • @lightxbulb 我已经在对您问题的评论中回答了这个问题。为了完整起见,我将在此答案中添加评论。
  • 所以这是未定义的行为,并且执行强制转换 (int)(const char*) 实际上没有背后的逻辑?我的意思是演员表没有产生任何合乎逻辑的结果?
  • @lightxbulb 确实,在任何 C 或 C++ 程序中,从指针到普通的、哑的、有符号的 int 类型的强制转换都没有意义。但是,进行强制转换本身并不是未定义的行为。请参阅上面引用的文字。
【解决方案2】:

没有进行投射。 "mamut" 是指向字符的指针,- 8 将对它进行指针运算。你是对的,它是未定义的行为,所以即使语义行为是指针算术,运行时行为实际上可以是任何东西。

【讨论】:

  • 那为什么地址和我从 (int)(const char*) 得到的数字不对应呢?
  • 我不明白你的意思。发布更多代码以准确说明您的问题。但我想强调的是,UB 实际上意味着任何事情都可能发生。过去UB不需要解释。从您的代码中删除 UB,然后我们可以进一步挖掘。
【解决方案3】:

您正在打印从“mamut”地址减去 8 个字节直到空终止符的字符串,即总共 8+5 = 13 字符

【讨论】:

    猜你喜欢
    • 2015-01-05
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2014-03-02
    相关资源
    最近更新 更多