va_arg和短 [英] va_arg and short

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

问题描述

六年前我正在编写一个由其他人编写的程序,当时广泛分发的是
。它还包括许多不同系统的makefile,所以我知道它已经编译了许多不同的
编译器。


我当使用va_arg获取类型为short的参数时出现编译错误。

这对我来说有点奇怪,所以我把它改成了int并编译了

就好了。


所以现在我想知道,va_arg和short的规则是什么?拒绝某些类型似乎很奇怪,但这就是编译器所做的。


- glen

I was compiling a program written by someone else about six years ago, and
widely distributed at the time. It also includes makefiles for many
different systems, so I know it has been compiled with many different
compilers.

I got compile errors when it used va_arg to fetch an argument of type short.
That seemed a little strange to me, so I changed it to int and it compiled
just fine.

So now I wonder, just what is the rule for va_arg and short? It would seem
strange to reject certain types, yet that is what the compiler did.

-- glen

推荐答案

2003-11-02,Glen Herrmannsfeldt< ga*@ugcs.caltech.edu>写道:
On 2003-11-02, Glen Herrmannsfeldt <ga*@ugcs.caltech.edu> wrote:
我在六年前编写了一个由其他人编写的程序,并且当时广泛分发。它还包括用于许多不同系统的makefile,所以我知道它已经编译了许多不同的编译器。

当我使用va_arg获取参数时,我遇到编译错误类型简短。
这对我来说有点奇怪,所以我把它改成了int并编译好了。

所以现在我想知道,对于什么是规则va_arg和短?拒绝某些类型似乎很奇怪,但这就是编译器所做的。
I was compiling a program written by someone else about six years ago, and
widely distributed at the time. It also includes makefiles for many
different systems, so I know it has been compiled with many different
compilers.

I got compile errors when it used va_arg to fetch an argument of type short.
That seemed a little strange to me, so I changed it to int and it compiled
just fine.

So now I wonder, just what is the rule for va_arg and short? It would seem
strange to reject certain types, yet that is what the compiler did.




C99:6.3.1.1,第2段


"如果int可以表示原始类型的所有值,则

值将转换为int;否则,它将转换为

unsigned int。这些被称为/整数促销/。"


C99:6.5.2.2,第6段


"如果表达式表示被调用函数的类型为

不包含原型,每个参数执行整数提升

,并且提升类型为float的参数

加倍。这些被称为/默认参数promotion /。


C99:6.5.2.2,第7段


"函数中的省略号表示法原型声明器导致

参数类型转换在最后声明的参数之后停止。

默认参数促销是在尾随参数上执行的。

- James



C99: 6.3.1.1, paragraph 2

"If an int can represent all the values of the original type, the
value is converted to an int; otherwise, it is converted to an
unsigned int. These are called the /integer promotions/."

C99: 6.5.2.2, paragraph 6

"If the expression that denotes the called function has a type that
does not include a prototype, the integer promotions are performed
on each argument, and arguments that have type float are promoted
to double. These are called the /default argument promotions/.

C99: 6.5.2.2, paragraph 7

"The ellipses notation in a function prototype declarator causes
argument type conversion to stop after the last declared parameter.
The default argument promotions are performed on trailing arguments."
-- James


文章< aE0pb.81932
In article <aE0pb.81932


HS4.680953@attbi_s01>

Glen Herrmannsfeldt< ga*@ugcs.caltech.edu>写道:
HS4.680953@attbi_s01>
Glen Herrmannsfeldt <ga*@ugcs.caltech.edu> writes:
当[某些代码]使用va_arg获取类型为short的
参数时,我遇到了编译错误。这对我来说有点奇怪,所以
我把它改成了int并且它编译得很好。

所以现在我想知道,va_arg和short的规则是什么?


程序员应该避免通过缩小的行程。类型为

va_arg()宏。


给予va_arg()的类型名称必须与实际类型相匹配

参数,无论它是什么。在调用缺少原型的函数时,或者其原型以,...结尾。 (实际的

参数与,...部分匹配),编译器有义务执行默认参数促销。这些替换(签名)

char并使用int替换,并使用double替换。他们还用一些更宽的类型替换了

unsigned char和unsigned short,但由于ANSI X3J11委员会

,因此不容易预测

更宽的类型人们在1985年左右选择了错误的规则。 (普通字符会在任何明智的平台上扩大

到签名int,但即使这不是保证
。)


因此,为了严格一致,可以编写如下代码:


case''我':/ *获取int * /

int_val = va_arg( ap,int);

...

休息;


case''s'':/ *获得一个(签名)短* /

short_val =(短)va_arg(ap,int);

...

休息;


case''S'':/ *获得一张未签名的短* *

#if USHRT_MAX> INT_MAX

ushort_val =(unsigned short)va_arg(ap,unsigned int);

#else

ushort_val =(unsigned short)va_arg(ap ,int);

#endif

...

休息;


注意icky需要一个#if测试,告诉哪个类型未签名

short变为默认参数促销。 (如果C使用

可预测的令人惊讶的规则unsigned promote to to unsigned,

#if不需要。当然,这个规则也会

必须使用一个说明如果普通字符未签名,那么

无论如何都会扩展到signed int,可能还有二级要求

对于任何此类系统,UCHAR_MAX不大于INT_MAX。

这对于现有实现来说不会是困难,

并且生成的规则更容易使用并且不要将b $ b从一个实现改变为另一个实现的方式,就像现在的那样

一样。)

拒绝某些类型似乎很奇怪,但这就是编译器所做的。
I got compile errors when [some code] used va_arg to fetch an
argument of type short. That seemed a little strange to me, so
I changed it to int and it compiled just fine.

So now I wonder, just what is the rule for va_arg and short?
It is up to the programmer to avoid passing "narrow" types to the
va_arg() macro.

The type name given to va_arg() must match the type of the actual
parameter, whatever it was. In a call to a function that lacks a
prototype, or whose prototype ends in ", ..." (where the actual
argument matches the ", ..." part), the compiler is obligated to
perform the "default argument promotions". These replace (signed)
char and short with int, and float with double. They also replace
unsigned char and unsigned short with some wider type, but the
wider type is not easily predicted because the ANSI X3J11 committee
folks chose the wrong rules in 1985 or so. (Plain char will widen
to signed int on any sensible platform, but even this is not
guaranteed.)

Hence, for strict conformance, one might code something like this:

case ''i'': /* obtain an int */
int_val = va_arg(ap, int);
...
break;

case ''s'': /* obtain a (signed) short */
short_val = (short)va_arg(ap, int);
...
break;

case ''S'': /* obtain an unsigned short */
#if USHRT_MAX > INT_MAX
ushort_val = (unsigned short)va_arg(ap, unsigned int);
#else
ushort_val = (unsigned short)va_arg(ap, int);
#endif
...
break;

Note the icky need for a "#if" test, to tell which type unsigned
short becomes under the default argument promotions. (Had C used
the "predictably surprising" rule "unsigned promotes to unsigned",
the #if would not be required. Of course, this rule would also
have to go with one that says that if plain char is unsigned, it
widens to signed int anyway, possibly with a secondary requirement
for UCHAR_MAX to be no greater than INT_MAX on any such system.
This would not have been a hardship for existing implementations,
and the resulting rules are far easier to work with and do not
change from one implementation to another the way the current ones
do.)
It would seem strange to reject certain types, yet that is what
the compiler did.




AC编译器不需要检测和拒绝这样的用法 - 它

属于未定义行为的广泛保护伞 - 但是一种类型的b $ b和聪明的编译器会做到这一点。 :-)

-

现实生活:风河系统Chris Torek

美国犹他州盐湖城(40 °39.22''N,111°50.29''W)+1 801 277 2603

电子邮件:忘了它 http://67.40.109.61/torek/index.html (目前)

阅读电子邮件就像搜索食物一样垃圾,感谢垃圾邮件发送者。



A C compiler is not required to detect and reject such usage -- it
falls under the broad umbrella of undefined behavior -- but a kind
and clever compiler will do it. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22''N, 111°50.29''W) +1 801 277 2603
email: forget about it http://67.40.109.61/torek/index.html (for the moment)
Reading email is like searching for food in the garbage, thanks to spammers.


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

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