【问题标题】:C++ store char array in int pointerC ++将char数组存储在int指针中
【发布时间】:2015-06-09 23:41:01
【问题描述】:

在这一行中是否进行了任何类型的转换(隐式、显式):

int *p= "hello there"; 

此外,从 C/C++ 的角度来看,这种说法的正确性是什么?

注意:它在 AVR-GCC 上编译,在其他编译器上失败。

【问题讨论】:

  • 错误:无法使用“const char [12]”类型的左值初始化“int *”类型的变量
  • @aslg 如果您知道如何正确操作,您可以这样做。事实上,这些东西在实践中被使用是有正当理由的。
  • 除非需要,否则不要这样做。像这样的事情在测试期间需要数周或更长时间才能发现,并可能导致未定义的行为。创建类型系统是有原因的。
  • @chris 此代码在 AVR-GCC 上编译。至于题外话,这个问题的目标是了解这样一行正在执行什么功能以及为什么它在 AVR-GCC 上编译。
  • @OAH 尝试在标准模式下调用您的编译器。 (对于 gcc 使用 -pedantic-std 开关,不确定 avr-gcc 是否完全相同)

标签: c++ c


【解决方案1】:

“在这一行中是否进行了任何类型的转换(隐式、显式):”

int *p= "hello there"; 

不,没有进行任何投射。

但在 C++ 中,您可以使用 reinterpret_cast<int*>const_cast<char*>,如下所示:

int *p= reinterpret_cast<int*>(const_cast<char*>("hello there")); 

See a working demo.

“此外,从 (C,C++) 的角度来看,您如何看待这种说法的正确性。”

嗯,这完全由此类声明的用户决定。当然不建议这样做(因为您遇到了未指定的1 行为),而且如果您不能 100% 确定自己在做什么,则很危险。

但至少两种语言都支持这样做。

C 的稍微短一点的变体是:

int *p= (int*)"hello there";

“注意:它在 AVR-GCC 上编译,在其他编译器上失败。”

好吧,我不知道您用于 AVR 交叉工具链的版本,但是任何最新版本的 GCC 都应该为该语句提供错误,例如

prog.cpp:3: error: cannot convert 'const char*' to 'int*' in initialization

See demo please

我正在使用一个相当旧版本的 GCC 来制作该演示:g++ 4.3.2。如果我得到正确的通知,最新的是 5.x,而且我很确定 to build a cross toolchain 可以用于 AVR。


1这与未定义的行为有细微的不同。仅取决于您的硬件与这些指针地址以及对齐设置一起使用。

【讨论】:

  • 如果char数组未正确对齐int,这可能会导致未定义的行为,如果p被读取或写入,则会由于严格的别名冲突而导致未定义的行为。
  • @MattMcNabb:它是未指定的,不是未定义的(除非 p 被读取或写入)。 C++ (since N3691, 2013-05-06) 5.2.9/13:“如果原始指针值表示内存中一个字节的地址A并且A满足T的对齐要求,那么得到的指针值表示相同的地址作为原始指针值,即A。任何其他此类指针转换的结果都是未指定。"
  • @MattMcNabb 当然会。我不是说你应该 100% 确定自己在做什么吗?
  • @πάνταῥεῖ 你说它是留给用户的,这表明它可能不会导致 UB
  • @MattMcNabb 当然,如果你确定你在做什么,你可以使用这样的代码。我的朋友每天都在撞公共汽车 ;-) ...
【解决方案2】:

回答您的问题(忽略“为什么这样做”cmets - 这是正确的)

你会的

int *p=(int*)"hello there";

【讨论】:

    【解决方案3】:

    此代码在 C 和 C++ 中是非法的。我们可能会猜测 AVR-GCC 会假装你写过:

    int *p = (int *)"hello there";
    

    您也许可以尝试通过写作来确认这一点:

    char *q = "hello there";
    int *p = q;
    

    并查看pq 是否拥有相同的地址。 (尽管无论哪种方式都不能完全确定)。

    最好了解如何在编译器报告非法代码错误或警告的模式下调用编译器。通常对于 gcc,-Wall -pedantic 会执行此操作,并且通常您还会指定标准版本,例如 -std=c99-std=gnu99


    假设代码被视为int *p = (int *)"hello there";。此代码可能会导致未定义或意外行为,因为 char 数组可能未正确对齐 int

    此外,如果您通过p 进行读取或写入,则会导致未定义的行为,因为这违反了严格的别名规则,即仅允许声明为int 或malloc 的变量以int 读取或写入'd 已写入 int 的空间(如果被读取)。

    【讨论】:

    • 我会测试你的代码并检查地址的对应关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多