gpt4 book ai didi

c++ - 指针整数强制转换的定义

转载 作者:行者123 更新时间:2023-12-01 13:37:56 26 4
gpt4 key购买 nike

我对从指针到整数和各种相关操作的转换的定义性(未定义性、实现定义性)感兴趣。我主要对 C11 感兴趣,但欢迎其他标准版本(甚至 C++)的答案。
对于这个问题,假设 C 实现提供 intptr_t .
考虑以下函数:

#include <assert.h>
#include <stdint.h>

int x;
int y;
int z[2];

void f1(void) {
int *p = &x;
intptr_t i = p;
}

void f2(void) {
int *p = &x;
intptr_t i1 = p;
intptr_t i2 = p;
assert(i1 == i2);
}

void f3(void) {
int *p1 = &x;
int *p2 = &y;
intptr_t i1 = p1;
intptr_t i2 = p2;
assert(i1 != i2);
}

void f4(void) {
int *p1 = &x;
intptr_t i1 = p1;
int *p2 = i1;
intptr_t i2 = p2;
assert(i1 == i2);
}

void f5(void) {
int *p1 = &z[0];
int *p2 = &z[1];
intptr_t i1 = p1;
intptr_t i2 = p2;
assert(i1 < i2);
}

  • 哪些函数调用未定义(实现定义)的行为?
  • 如果使用 void* 有什么变化吗?而不是 int* ?任何其他数据类型作为指针的目标怎么样?
  • 如果我使用来自 int* 的显式强制转换,有什么变化吗?至 intptr_t然后回来? (因为 GCC 对类型转换发出警告而询问。)
  • 其中assert s 保证永远不会触发?
  • 最佳答案

    这就是 C11 标准对 intptr_t 的说明:

    7.20.1.4 Integer types capable of holding object pointers

    The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

    intptr_t
    uintptr_t 也是如此(除了有符号 -> 无符号)。
    同样来自“6.5.4p3 Cast 操作符”:

    Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.


    其中 6.5.16.1 没有提到将指针分配给整数类型,反之亦然(除了 0 常量)。这意味着您在分配时确实需要强制转换,gcc 只允许它作为编译器扩展(并且它根本不编译 -pedantic-errors )
    至于在这些转换中返回的确切值,这就是标准所说的:

    6.3.2.3 Pointers

    p5An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, [...]

    p6Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. [...]



    您拥有的基本保证是:
    int x;
    (int*) (void*) (intptr_t) (void*) &x == &x;
    /* But the void* casts can be implicit */
    (int*) (intptr_t) &x == &x;
    并且没有必要强制转换为相同的整数。例如,以下情况可能为真:
    int x;
    (intptr_t) &x != (intptr_t) &x;
    在必要时添加强制转换,并将您的断言转换为返回(因为 assert(false) 是未定义的行为),您的函数都没有未定义的行为,但是 f2 , f4f5可能是假的。 f3必须为真,因为两个整数必须不同才能转换为不同的指针。

    关于c++ - 指针整数强制转换的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63077625/

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