不推荐使用“在左值中使用强制转换表达式”。 [英] Avoiding "use of cast expressions in lvalues is deprecated"

查看:210
本文介绍了不推荐使用“在左值中使用强制转换表达式”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我们有以下宏:


#define NEXT(type,p)(*((类型*) )(p))++)


它为一个简单的虚拟机提供了一种方法,可以将可变大小的数据戳入一个pcode数组



例如,


NEXT(byte,pcode)= PUSH;

NEXT(int,pcode)=常量;


但这项技术现在似乎已被弃用。对我来说似乎相当安全(指针总是可以互相转换)而且我看不到任何明显的

和有效的方法来解决错误(特别是在pcode

翻译本身)


提前感谢,

Steve Donovan。

解决方案

st ******** *****@gmail.com 写道:


大家好,


我们有以下宏:


#define NEXT(type,p)(*((type *)(p))++)


它提供一种将可变大小的数据戳入pcode数组的方法

用于简单的VM。

例如,


NEXT(byte ,pcode)= PUSH;

NEXT(int,pcode)=常数;


但这项技术现在似乎已被弃用。



它在标准C中从未有效,使用强制转换表达式作为左值

是GNU扩展名。
< blockquote class =post_quotes>


我似乎相当安全(指针总是可以互相转换)



所以可以int和double,但你不希望((int)d)++编译

当d被声明为double时,你呢?为什么指针应该是不同的?
不同? (在回答之前,再考虑一下。)


我无法看到任何明显的

和有效的方法绕过错误(特别是在pcode

解释器本身)



" Efficient"?很可能用单独的

写和增量语句重写代码将产生相同的目标代码,假设你正在编译并启用了优化,那么这将是一个不错的 br $>
编译器。


而不是


*((int *)p)++ = k;


使用


*(int *)p = k;


后跟


p =(int *)p + 1; / *如果p的类型为void * * /





p + = sizeof(int); / *如果p是char *类型或另一个字节大小的类型

* /


您还应该真正处理大小的不同可能性/>
和int的表示,以及任何对齐问题,如果你想

确保代码可以移植到其他平台,但那些是

单独的科目。


在文章< 11 ********************** @ e3g2000cwe.googlegroups。 com>,

< st ************* @ gmail.comwrote:


> #define NEXT(type,p)(*((type *)(p))++)

它提供了一种将可变大小的数据戳入pcode数组的方法
简单的VM。



[...]


>但这项技术现在似乎已被弃用。



它从来都不是标准C.一些早期的C编译器允许使用

和第一个ANSI C的一些草稿标准,并允许通过gcc

作为扩展。


>对我来说似乎相当安全(指针可以永远是互相转换的)



指针可以在大多数实现中互相转换。如果不同类型的指针有不同的表示形式,那么它可能不会起作用。

(它将在p中存储什么?)当然它只会起作用<如果

问题中的类型和处理器没有对齐问题,则需要



在那些应该的系统上通过使用联合类型,你通常可以达到相同的效果:


union {

int * i;

char * c;

} p;


ii = p.i ++;

cc = p.c ++;


或使用泛型 unsigned char指针,可能是这样的:


unsigned char * p,* t;


#define NEXT(type,p,t) ((t)=(p),p + = sizeof(类型),(类型*)*(t))


- Richard

<

Richard Tobin写道:


它从来都不是标准C.一些早期的C编译器允许使用

和第一个ANSI C标准的一些草案,并且gcc

允许作为扩展。



现在我从来不知道 - 有时从

a编译器学习语言是不明智的。


#define NEXT(type,p,t)((t)=(p),p + = sizeof(type),(type *)*(t))



谢谢大家,这正是我所需要的 - 标准的思考方式

关于

这个问题,以及做牛仔方法的陷阱。


steve d。


Hi guys,

We have the following macro:

#define NEXT(type,p) (*((type*)(p))++)

It provides a way to poke variable sized data into an array of pcode
for a simple VM.
e.g,

NEXT(byte,pcode) = PUSH;
NEXT(int,pcode) = constant;

But this technique now seems to be deprecated. It seems fairly safe to
me (pointers can always be interconverted) and I can''t see any obvious
and efficient way to get around the error (particularly in the pcode
interpreter itself)

thanks in advance,
Steve Donovan.

解决方案

st*************@gmail.com wrote:

Hi guys,

We have the following macro:

#define NEXT(type,p) (*((type*)(p))++)

It provides a way to poke variable sized data into an array of pcode
for a simple VM.
e.g,

NEXT(byte,pcode) = PUSH;
NEXT(int,pcode) = constant;

But this technique now seems to be deprecated.

It''s never been valid in standard C, using cast expressions as lvalues
was a GNU extension.

It seems fairly safe to
me (pointers can always be interconverted)

So can int and double, but you wouldn''t expect ((int) d)++ to compile
when d is declared as double, would you? Why should pointers be any
different? (Before answering, think about it a little bit more.)

and I can''t see any obvious
and efficient way to get around the error (particularly in the pcode
interpreter itself)

"Efficient"? It is quite likely that rewriting the code with separate
write and increment statements will generate identical object code,
assuming you''re compiling with optimisations enabled, and a decent
compiler.

Instead of

*((int*) p)++ = k;

Use

*(int *) p = k;

followed by

p = (int *) p + 1; /* if p is of type void* */

or

p += sizeof(int); /* if p is of type char* or another byte-sized type
*/

You should really also handle the different possibilities for the size
and representation of an int, and any alignment issues, if you want to
make sure the code is portable to other platforms, but those are
separate subjects.


In article <11**********************@e3g2000cwe.googlegroups. com>,
<st*************@gmail.comwrote:

>#define NEXT(type,p) (*((type*)(p))++)

It provides a way to poke variable sized data into an array of pcode
for a simple VM.

[...]

>But this technique now seems to be deprecated.

It''s never been standard C. It was allowed by some early C compilers
and in some drafts of the first ANSI C standard, and is allowed by gcc
as an extension.

>It seems fairly safe to
me (pointers can always be interconverted)

Pointers can be interconverted on most implementations. It may not
work if different kinds of pointer have different representations
(what''s it going to store back in p?) and of course it will only work
if there are no alignment problems for the types and processor in
question.

On those systems where it "ought" to work, you can usually achieve the
same effect by using a union type:

union {
int *i;
char *c;
} p;

ii = p.i++;
cc = p.c++;

or by using a "generic" unsigned char pointer, perhaps something like:

unsigned char *p, *t;

#define NEXT(type, p, t) ((t) = (p), p += sizeof(type), (type *)*(t))

-- Richard


Richard Tobin wrote:

It''s never been standard C. It was allowed by some early C compilers
and in some drafts of the first ANSI C standard, and is allowed by gcc
as an extension.

Now that I never knew - sometimes it''s unwise to learn a language from
a compiler.

#define NEXT(type, p, t) ((t) = (p), p += sizeof(type), (type *)*(t))

Thanks guys, that''s exactly what I needed - the standard way to think
about
the problem, and the pitfalls of doing it the cowboy method.

steve d.


这篇关于不推荐使用“在左值中使用强制转换表达式”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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