相关疑难解决方法(0)

不相关指针的相等比较可以评估为真吗?

关于和运营商的C标准第6.5.9节规定如下:==!=

2下列之一应持有:

  • 两个操作数都有算术类型;
  • 两个操作数都是指向兼容类型的限定或非限定版本的指针;
  • 一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的void的指针; 要么
  • 一个操作数是一个指针,另一个是空指针常量.

...

6 两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和在其开头的子对象)或函数,两者都是指向同一对象的最后一个元素的指针数组对象,或者一个是指向一个数组对象末尾的指针,另一个是指向不同数组对象的开头的指针,该数组对象恰好跟随地址空间中的第一个数组对象.109)

7出于这些运算符的目的,指向不是数组元素的对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型.

脚注109:

109)两个对象在内存中可能相邻,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,或者因为实现选择放置它们,即使它们是不相关的.如果先前的无效指针操作(例如数组边界外的访问)产生了未定义的行为,则后续比较也会产生未定义的行为.

这似乎表明您可以执行以下操作:

int a;
int b;
printf("a precedes b: %d\n", (&a + 1) == &b);
printf("b precedes a: %d\n", (&b + 1) == &a);
Run Code Online (Sandbox Code Playgroud)

这应该是合法的,因为我们使用地址一个元素超过数组的末尾(在这种情况下是一个被视为大小为1的数组的单个对象),而不解除引用它.更重要的是,1如果一个变量在内存中紧跟另一个变量,则需要输出这两个语句中的一个.

但是,测试似乎没有把它弄平.鉴于以下测试计划:

#include <stdio.h>

struct s {
    int a;
    int b;
};

int main()
{
    int a;
    int b;
    int *x = &a;
    int *y = &b;

    printf("sizeof(int)=%zu\n", …
Run Code Online (Sandbox Code Playgroud)

c pointers language-lawyer

37
推荐指数
4
解决办法
1137
查看次数

这个gcc / clang过去一指针比较行为是符合标准还是非标准?

即使C标准明确认识到,指向一个对象“刚刚过去”的地址可能偶然地与指向“指向”另一个不相关对象的地址相等,但gcc和clang似乎都在假设没有指针的情况下运行如示例所示,观察到指向刚刚超过一个对象的对象可能指向另一个对象:

#include <stdio.h>

int x[1],y[1];
int test1(int *p)
{
    y[0] = 1;
    if (p==x+1)
        *p = 2; // Note that assignment is to *p and not to x[1] !!!
    return y[0];
}
int test2(int *p)
{
    x[0] = 1;
    if (p==y+1)
        *p = 2; // Note that assignment is to *p and not to y[1] !!!
    return x[0];
}

int (*volatile test1a)(int *p) = test1;
int (*volatile test2a)(int *p) = test2;

int main(void) {
    int q;
    printf("%llX\n",(unsigned long long)y - …
Run Code Online (Sandbox Code Playgroud)

c optimization gcc clang

9
推荐指数
1
解决办法
155
查看次数

标签 统计

c ×2

clang ×1

gcc ×1

language-lawyer ×1

optimization ×1

pointers ×1