加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

评估/访问结构

发布时间:2020-12-16 06:02:52 所属栏目:百科 来源:网络整理
导读:考虑相同代码的两个稍微不同的版本: struct s{ int dummy[1];};volatile struct s s;int main(void){ s; return 0;} 和 struct s{ int dummy[16];};volatile struct s s;int main(void){ s; return 0;} 以下是我使用gcc 4.6.2为他们: _main: pushl %ebp mo
考虑相同代码的两个稍微不同的版本:
struct s
{
  int dummy[1];
};

volatile struct s s;

int main(void)
{
  s;
  return 0;
}

struct s
{
  int dummy[16];
};

volatile struct s s;

int main(void)
{
  s;
  return 0;
}

以下是我使用gcc 4.6.2为他们:

_main:
        pushl   %ebp
        movl    %esp,%ebp
        andl    $-16,%esp
        call    ___main
        movl    _s,%eax
        xorl    %eax,%eax
        leave
        ret

        .comm   _s,4,2

_main:
        pushl   %ebp
        movl    %esp,%esp
        call    ___main
        xorl    %eax,64,5

请注意在第二种情况下无法访问s.

是否是编译器错误,或者我只是处理C标准的以下语句,gcc开发人员只是选择了这样一个奇怪的实现定义,并且仍然遵循规则:

What constitutes an access to an object that has volatile-qualified type is implementation-defined.

这个差异的原因是什么?我自然会期望整个结构被访问(或不被访问,我不知道),不管其大小和内部的内容.

附:在这种情况下,您的编译器(非gcc或更新的gcc)是做什么的? (如果这是您要解决的唯一部分,请在评论中回答这个最后一个问题,因为这不是主要问题,更多是好奇的问题).

解决方法

这个问题的C和C之间有区别,这说明了发生了什么.

铛 – 3.4

当将这些片段中的任一个编译为C时,发出的程序集在任何情况下都不引用.实际上发出了两个警告:

volatile.c:8:2:warning:表达式结果未使用;分配给一个变量来强制易变负载[-Wunused-volatile-lvalue]
S;

在C99模式下编译时,不会发出这些警告.如this blog post和this GCC wiki entry from the question comments中所述,在这种情况下使用s会导致C中的lvalue-to-rvalue转换,而不是C中的.这通过检查C的Clang AST来确认,因为来自LvalueToRValue的ImplicitCastExpr在C中生成的AST中不存在. (AST不受struct的大小的影响).

Clang源的快速grep揭示了在聚合表达式的排放中:

case CK_LValueToRValue:
// If we're loading from a volatile type,force the destination
// into existence.
if (E->getSubExpr()->getType().isVolatileQualified()) {
  EnsureDest(E->getType());
  return Visit(E->getSubExpr());
}

EnsureDest强制排放堆栈槽,大小和类型为表达式.由于优化器不允许删除易失性访问,它们分别保留在IR和输出asm中的标量加载/存储和memcpy.鉴于上述情况,这是我期望的行为.

GCC-4.8.2

在这里,我观察到与问题相同的行为.但是当我改变表达式时,到s.dummy;访问不会出现在任一版本中.我不熟悉gcc的内部,因为我使用LLVM,所以我不能猜测为什么会发生这种情况.但是基于上述观察结果,我会说这是一个由于不一致而导致的编译器错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读