在地址比较下,具有自动存储持续时间的两个不同对象是否可以相等?

蜜蜂绳

特别是允许不同函数中的两个自动变量的地址相等,如下所示:

下沉

#include <stdio.h>
#include <stdlib.h>

void sink(void *l, void *r) {
    puts(l == r ? "equal" : "not equal");
    exit(0);
}

main.c

typedef struct { char x[32]; } Foo;

void sink(void *l, void *r);

Foo make(void *p) {
    Foo f2;
    sink(&f2, p);
    return f2;
}

int main() {
    Foo f1 = make(&f1);
}

我希望这可以not equal作为f1f2分别打印出来使用gcc可以得到not equal,但是使用本地版本的clang 3.8 1时,将其equal编译为clang -O1 sink.c main.c2可以打印

拆卸makemain...

0000000000400570 <make>:
  400570:   53                      push   rbx
  400571:   48 89 fb                mov    rbx,rdi
  400574:   e8 d7 ff ff ff          call   400550 <sink>
  400579:   48 89 d8                mov    rax,rbx
  40057c:   5b                      pop    rbx
  40057d:   c3                      ret    
  40057e:   66 90                   xchg   ax,ax

0000000000400580 <main>:
  400580:   48 83 ec 28             sub    rsp,0x28
  400584:   48 8d 7c 24 08          lea    rdi,[rsp+0x8]
  400589:   48 89 fe                mov    rsi,rdi
  40058c:   e8 df ff ff ff          call   400570 <make>
  400591:   31 c0                   xor    eax,eax
  400593:   48 83 c4 28             add    rsp,0x28
  400597:   c3                      ret    

...我们看到make似乎根本没有创建Foo f2对象,它只是sink使用现有的rdirsi分别lr参数)进行调用它们的传递main和相同:第一个rdi是,是指向放置返回值的位置的隐藏指针,第二个是&f1,因此我们希望它们是相同的。


1我检查了7.0以下版本,其行为大致相同。

2它发生在-O1-O2-O3,但不是-O0打印出来的not equal

MM

C11标准第6.5.9 / 6部分说:

当且仅当两个都是空指针时,两个指针比较相等,两个都是指向同一对象的指针(包括指向对象和它的开始处的子对象的指针)或函数,都是指向同一数组的最后一个元素的指针对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象的起点的指针,该数组对象恰好紧随地址空间中的第一个数组对象。

在此代码中,没有列出的条件成立;&f1&f2是指向不同对象的指针,并且一个不是另一个的子对象。

因此,指针不能比较相等。编译器报告equal不符合要求。


注意:如果有人对的合法性有疑问Foo f1 = make(&f1);请参阅此问题很好,自动对象的生存期从前一个开始{

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

具有自动存储持续时间的“太大”对象是不确定的行为吗?

比较两个比较大的对象是否相等

具有自动存储持续时间的变量的地址可以在其定义中使用吗?

如何比较两个ctypes对象是否相等?

C#比较两个对象是否相等

自动检查两个对象是否相等?

从另一个线程访问具有自动存储持续时间的对象

如何转换具有不同持续时间的两个属性?

如何比较来自不同对象的两个日期值,设置它们的格式并测试是否相等?

是否可以将 page_size 存储到具有静态存储持续时间的对象中?

检查对象是否相等,但仅比较两个对象中定义的键

断言动态集合中两个不同的对象是否具有相同的值

检查具有不同结构的两个对象是否相同?

具有指向相同对象的具有不同值的两个指针是否是未定义的行为?

比较两个相同长度但在JS中内部具有不同对象ID的数组

比较两个List <T>对象是否相等,忽略顺序

Firebase安全规则:比较两个对象是否相等?

比较两个整数对象是否相等,无论类型如何

两个不同类的Java对象是否应该相等?

javascript比较具有不同对象的两个数组

检查两个对象是否相等,null匹配所有对象

如何检查两个Map对象是否相等?

检查两个对象是否相等 React Native

检查飞镖中的两个对象是否相等

比较具有不同时区的两个“时间”对象

将两个具有不同持续时间的 WAV 文件合并在一起,以使结束时间匹配

合并来自两个不同对象数组的具有相应键值的对象

具有两个以不同对象作为父对象的构造函数的类

如何比较具有相同对象属性的两个值?