别名中的别名 [英] Aliasing in assignment

查看:97
本文介绍了别名中的别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在没有

优化的情况下编译时在Solaris 10上崩溃:


typedef结构节点;


struct Node {

int val;

Node * next;

};


int main(void)

{

节点b = {2,0};

节点a = {1,& b};


a = *(a.next);


返回a.val;

}


如果在写入之后,a.next已经设置为null,则会再次取消引用a.next(出于某些不明原因)。


这是谁的错误,程序员还是编译器?最初我认为这是程序员的错,因为在访问a.next和写入a之间没有序列

分,但是如果那个

使代码变得非法,那么以下无处不在的成语如何:


Node * p =& a;

p = p-> next;


在这里,我们都访问p并写入p而没有序列点在

之间。有什么区别,或者有什么?


提前致谢。

Lauri

The following code crashes on Solaris 10 when compiled without
optimization:

typedef struct Node Node;

struct Node {
int val;
Node *next;
};

int main(void)
{
Node b = { 2, 0 };
Node a = { 1, &b };

a = *(a.next);

return a.val;
}

What happens is that after a has been written to, and a.next has been
set to null, a.next is dereferenced again (for some obscure reason).

Whose fault is this, the programmer''s or the compiler''s? Initially I
thought that it''s the programmer''s fault since there are no sequence
points between the access to a.next and the writing to a, but if that
made the code illegal, how about the following ubiquitous idiom:

Node* p = &a;
p = p->next;

Here, too, we both access p and write to p without sequence points in
between. What''s the difference, or is there any?

Thanks in advance.
Lauri

推荐答案

在文章< et ********** @ oravannahka.helsinki.fi>,

Lauri Alanko< la@iki.fiwrote:
In article <et**********@oravannahka.helsinki.fi>,
Lauri Alanko <la@iki.fiwrote:

>以下代码在没有
优化的情况下编译时在Solaris 10上崩溃:
>The following code crashes on Solaris 10 when compiled without
optimization:



[使其可编译的剪辑位]

[snip bits that make it compileable]


节点b = {2,0};

节点a = {1,& b} ;


a = *(a.next);
Node b = { 2, 0 };
Node a = { 1, &b };

a = *(a.next);


>在写入之后,a.next被设置为null,a.next会发生什么?再次被解除引用(出于一些不明确的原因)。

这是谁的错误,程序员或编译器的?最初我认为这是程序员的错,因为在访问a.next和写入a,
>What happens is that after a has been written to, and a.next has been
set to null, a.next is dereferenced again (for some obscure reason).

Whose fault is this, the programmer''s or the compiler''s? Initially I
thought that it''s the programmer''s fault since there are no sequence
points between the access to a.next and the writing to a,

$之间没有顺序
点。 b
$ b据我所知,访问旧值只是为了确定要存储的新值(在a.next中访问指针以确定在哪里
找到要存储的值,取消引用指针以获取存储的值),这意味着根据n869的6.5#2,它是完全可以接受的,这是

如果那是问题就会使它不确定的段落。


所以,除非我遗漏了什么,这看起来像编译器错误。

dave


-

Dave Vandervies dj ******@csclub.uwaterloo.ca

嗯,这在逻辑上是一致的和有趣的。这似乎是所有数学家都需要的b $ b。

- 可怕的恶魔修道院中的詹姆斯·赖登

As far as I can tell, the old value is accessed only to determine the
new value to be stored (access pointer in a.next to determine where to
find value to store, dereference pointer to get value to store), which
means it''s perfectly acceptable according to 6.5#2 of n869, which is
the paragraph that would make it undefined if that were the problem.

So unless I''m missing something, this looks like a compiler bug.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Well, it''s logically consistent and interesting. That appears to be
all mathematicians need.
--James Riden in the scary devil monastery


Lauri Alanko < l ... @ iki.fiwrote:
Lauri Alanko <l...@iki.fiwrote:

以下代码在没有

优化的情况下编译时在Solaris 10上崩溃:


typedef结构节点;


结构节点{

int val;

节点*下一个;

};


int main(无效)

{

节点b = { 2,0};

节点a = {1,& b};
The following code crashes on Solaris 10 when compiled without
optimization:

typedef struct Node Node;

struct Node {
int val;
Node *next;
};

int main(void)
{
Node b = { 2, 0 };
Node a = { 1, &b };



这违反了约束6.7.8p4,其中规定

初始值必须是常数。


尝试...


静态节点b = {2,0};

静态节点a = {1,& b};

This violates constraint 6.7.8p4 which states that an
initialisor has to be a constant.

Try...

static Node b = { 2, 0 };
static Node a = { 1, &b };


>

a = *(a.next);

返回a.val;
>
a = *(a.next);
return a.val;



请注意,1和2都不是main到

返回主机的可移植值。使用0,EXIT_SUCCESS或EXIT_FAILURE;

来自< stdlib.h>的后两者。

Note that neither 1 nor 2 are portable values for main to
return to the host. Use 0, EXIT_SUCCESS or EXIT_FAILURE;
the latter two from <stdlib.h>.


}

如果在写入之后,并且a.next

已设置为null,则会再次取消引用a.next(对于某些
$ b $) b模糊的原因)。


这是程序员还是程序员的错误?
}

What happens is that after a has been written to, and a.next
has been set to null, a.next is dereferenced again (for some
obscure reason).

Whose fault is this, the programmer''s or the compiler''s?



一个错误是程序员的错误。如果修复没有解决

问题,那么它似乎是编译器的。


-

Peter

One fault is the programmer''s. If fixing that doesn''t fix the
problem, then it appears to be the compiler''s.

--
Peter


Peter Nilsson写道:
Peter Nilsson wrote:

Lauri Alanko< l ... @ iki.fiwrote:
Lauri Alanko <l...@iki.fiwrote:

>以下代码在没有优化的情况下编译时在Solaris 10上崩溃:

typedef struct Node节点;

struct Node {
int val;
Node * next;
};

int main(void)
{
节点b = {2,0};
节点a = {1,& b};
>The following code crashes on Solaris 10 when compiled without
optimization:

typedef struct Node Node;

struct Node {
int val;
Node *next;
};

int main(void)
{
Node b = { 2, 0 };
Node a = { 1, &b };



这违反了约束6.7.8p4,该约束声明

初始值必须是常量。


This violates constraint 6.7.8p4 which states that an
initialisor has to be a constant.



否;引用的段落说


初始化器中对象的所有表达式

^^^^^^^^^^^^^^^^^ ^^

有静态存储持续时间应该是常量表达式

^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^

或字符串文字。


(强调我的。)

No; the cited paragraph says

All the expressions in an initializer for an object that
^^^^^^^^^^^^^^^^^^
has static storage duration shall be constant expressions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
or string literals.

(Emphasis mine.)


>这是谁的错误,程序员或编译器的?
>Whose fault is this, the programmer''s or the compiler''s?



一个错误是程序员的错误。如果修复没有解决

问题,那么它似乎是编译器的。


One fault is the programmer''s. If fixing that doesn''t fix the
problem, then it appears to be the compiler''s.



我想(请注意,我说我想想)这是编译器的错。


-

Eric Sosman
es ***** @ acm -dot-org.inva 盖子


这篇关于别名中的别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆