铸为左值 [英] cast-as-lvalue

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

问题描述

我最近将我的Arch Linux系统升级到GCC 3.4,并发现之前已接受的行为(cast-as-lvalue)已被标记为已弃用,

并将在GCC 3.5中停止运作。这导致了几个版本打破了b
,最值得注意的是elfutils。


大概这个行为不是C标准的一部分,因此它是

像许多其他非标准GCC扩展一样被删除。无论如何,我的问题不是关于GCC或任何编译器的细节或政治问题。


我试图解决的大部分代码都涉及到如下所示:


*((some_type *)ptr)++;


在这种情况下,所需的行为是增加指针好像它是
是(some_type *)。在某些情况下,指针被输入为void,在

其他情况下它具有特定类型,但无论编译器是否需要

将其视为不同的类型正在递增它。


现在我个人认为施放左值是一种非常合理的方式来攻击这个问题,但显然不够它被弃用了。我的

问题是,如何获得相同的确切行为,但在C

规格内?


我目前本能是做如下事情。


假设当前代码是:


foo * ptr;

*((bar *)ptr)++;


我会做以下事情:


foo * ptr;

bar * temp =(bar *)ptr;

* temp ++;

ptr =(foo *)temp;


有没有更好的方法呢?这似乎是相当多的额外

代码,以避免(至少对我来说)表达这种行为的逻辑方式




- Mike

解决方案



2004年8月23日星期一,Michael Baehr写道: blockquote class =post_quotes>
在这种情况下,所需的行为是将指针递增,就像它是(some_type *)一样。在某些情况下,指针被输入为void,在其他情况下它具有特定类型,但无论编译器是否需要在增加它时将其视为不同类型。


[无效的C代码] foo * ptr;
*((bar *)ptr)++;


[有效C代码] foo * ptr;
bar * temp =(bar *)ptr;
* temp ++;
ptr =(foo *)temp;




这样可行,但你可以将它压缩成一行并且

输掉临时的:


foo * ptr;

ptr =(foo *)((bar *)ptr + 1);


注意如果''foo''''无效'',你也可以放弃多余的演员:


void * ptr;

ptr =(bar *)ptr + 1;


HTH,

-Arthur


8月23日星期一2004年,Michael Baehr写道:

我最近将我的Arch Linux系统升级到GCC 3.4,并发现以前接受的行为(cast-as-lvalue)现在是标记为已弃用,
将在GCC 3.5中停止运行。这导致了几个构建中断,最显着的是elfutils。

大概这种行为不是C标准的一部分,因此它像许多其他非标准GCC扩展一样被切除。无论如何,我的问题不是关于GCC或任何编译器的细节或政治。

我正在尝试解决的大部分代码涉及以下内容:

*((some_type *)ptr)++;




这不是一个左右角色,而是一个普通的演员阵容。标准C,虽然

结果通常是未定义的。


AFAIK,等效的演员价值将是:


((some_type)* ptr)++;


2004年8月24日星期二,Jarno A Wuolijoki写道:

2004年8月23日星期一,Michael Baehr写道:

*((some_type *)ptr)++;



这不是左倾,而是普通演员。标准C,虽然
结果通常是未定义的。




我重新吸引我的大脑并回复我的话:

*((some_type *)ptr)++; !=(*((some_type *)ptr))++;


叹气。为什么在抓住这些细节之前我总是点击发送..


I recently upgraded my Arch Linux system to GCC 3.4, and found out that a
previously accepted behavior (cast-as-lvalue) is now marked as deprecated,
and will cease to function in GCC 3.5. This has caused several builds to
break, most notably elfutils.

Presumably this behavior is not part of the C standard and it is thus
being excised like many other nonstandard GCC extensions. Regardless, my
question is not about the specifics or politics of GCC or any compiler.

Much of the code I''m trying to fix involves things like the following:

*((some_type *) ptr)++;

The desired behavior in this case is to increment the pointer as if it
were a (some_type *). In some cases, the pointer is typed as void, in
other cases it has a specific type, but regardless the compiler needs to
treat it as a different type when it is incrementing it.

Now I personally think cast-as-lvalue is a very logical way to attack this
problem, but apparently enough don''t that it''s been deprecated. My
question, then, is how to get the same exact behavior, but within the C
spec?

My current instinct is to do something as follows.

Assume the current code is:

foo *ptr;
*((bar *) ptr)++;

I would do the following:

foo *ptr;
bar *temp = (bar *)ptr;
*temp++;
ptr = (foo *)temp;

Is there any better way to do this? This seems like quite a bit of extra
code to avoid what (at least to me) looks like the logical way of
expressing this behavior.

-- Mike

解决方案


On Mon, 23 Aug 2004, Michael Baehr wrote:


The desired behavior in this case is to increment the pointer as if it
were a (some_type *). In some cases, the pointer is typed as void, in
other cases it has a specific type, but regardless the compiler needs to
treat it as a different type when it is incrementing it.
[not valid C code] foo *ptr;
*((bar *) ptr)++;
[valid C code] foo *ptr;
bar *temp = (bar *)ptr;
*temp++;
ptr = (foo *)temp;



This works, but you might as well compress it into one line and
lose the temporary:

foo *ptr;
ptr = (foo *)((bar *)ptr + 1);

Note that if ''foo'' is ''void'', you can drop the redundant cast, too:

void *ptr;
ptr = (bar *)ptr + 1;

HTH,
-Arthur


On Mon, 23 Aug 2004, Michael Baehr wrote:

I recently upgraded my Arch Linux system to GCC 3.4, and found out that a
previously accepted behavior (cast-as-lvalue) is now marked as deprecated,
and will cease to function in GCC 3.5. This has caused several builds to
break, most notably elfutils.

Presumably this behavior is not part of the C standard and it is thus
being excised like many other nonstandard GCC extensions. Regardless, my
question is not about the specifics or politics of GCC or any compiler.

Much of the code I''m trying to fix involves things like the following:

*((some_type *) ptr)++;



This isn''t cast-as-lvalue but a normal cast. Standard C, though the
result is often undefined.

AFAIK, the equivalent cast-as-lvalue would be:

((some_type)*ptr)++;


On Tue, 24 Aug 2004, Jarno A Wuolijoki wrote:

On Mon, 23 Aug 2004, Michael Baehr wrote:

*((some_type *) ptr)++;



This isn''t cast-as-lvalue but a normal cast. Standard C, though the
result is often undefined.



I re-engage my brain and take my word back:
*((some_type *) ptr)++; != (*((some_type *) ptr))++;

Sigh. Why is it that I always hit send before catching these details..


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

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