C89,size_t和long [英] C89, size_t, and long

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

问题描述

嘿,


我正在阅读C99理由,它有以下两个安静的改变

段落:


6.5.3.4:随着long long和extended整数

类型的引入,sizeof运算符可能会产生一个超出范围的值。

unsigned long。


6.5.6:随着长long和扩展整数

类型的引入,指针的减法可能会返回超过

范围的值。


C89是否要求sizeof()的结果符合unsigned long,

并且指针减法结果适合长?如果是,那么MS

Win64实现不符合C89(虽然sizeof case可能是
可辩论,我想,我们当然可以向malloc请求超过ULONG_MAX

字节,并获得指针算术,它需要超过(无符号)

长)。如果不是,为什么这两段,如果那些依赖于长期足够大的程序已经被打破了?


Yevgen

解决方案

Yevgen Muntyan在03/14/07 14:26写道:


嘿,


我正在阅读C99理由,它有以下两个安静更改

段落:


6.5.3.4:With引入长long和扩展整数

类型,sizeof运算符可能会产生一个超出无符号长整数范围的值。


6.5.6:随着长long和扩展整数

类型的引入,指针的减法可能返回超过
$ b的值$ b范围很长。


C89是否需要sizeof()的结果符合unsigned long,

和指针减法结果适合多久?



"是"和几乎,分别。 C89提供了一套固定的

整数类型,其中{,un}签名long是最宽的。

实现可以免费提供其他类型的

表现得像整数,但它们不是整数类型。 as

C89定义了它们。 C89还要求size_t和ptrdiff_t

为整数类型的别名。所以它们不能超过
长。如果一个实现提供了更广泛的类型,它们就不是b&b整数类型因此不适合size_t和

ptrdiff_t。


在长度与指针宽度相同的机器上

(更一般地说,没有比它们的指针宽一些),这意味着

ptrdiff_t不能足够宽以表达所有

指针减法的结果。一个简单的例子:


char * p = malloc(LONG_MAX + 2u); / *假设成功* /

char * q = p + LONG_MAX + 2u;

ptrdiff_t delta = q - p;


我们现在将p<但是(可能)delta< 0.


如果是,那么MS

Win64实现不符合C89(虽然sizeof case可能是

可辩论,我想,我们当然可以向malloc请求超过ULONG_MAX

字节,并获得需要超过(无符号)

长的指针算术。如果不是,为什么这两个段落,如果依赖于长期足够大的程序已经被打破了?



我不知道MS的'Win64实现是否足以评论

是否已被破坏。至于假设

size_t和ptrdiff_t的程序并不比很长,不是:它们不是根据C89规则打破的,因为C89暗示了真相。

假设。 C99改变了规则,允许实施 -

定义为异国情调。要在整数类型中计算的类型,

这个更改可能会破坏一些依赖旧的
规则的程序。因此,安静的变化警告。


-
Er ****** ***@sun.com


Eric Sosman写道:


Yevgen Muntyan写道03/14/07 14:26,:


>嘿,

我正在阅读C99理由,它有以下两个安静更改
段落:

6.5.3.4:随着long long和extended integer
类型的引入,sizeof运算符可能会产生超出范围的值
of unsigned long。

6.5.6:随着long long和extended integer
类型的引入,指针的减法可能会返回一个超出的值
范围很长。

C89是否需要sizeof()的结果符合unsigned long,
并且指针减法结果适合长?



"是"和几乎,分别。 C89提供了一套固定的

整数类型,其中{,un}签名long是最宽的。

实现可以免费提供其他类型的

表现得像整数,但它们不是整数类型。 as

C89定义了它们。 C89还要求size_t和ptrdiff_t

为整数类型的别名。所以它们不能超过
长。如果一个实现提供了更广泛的类型,它们就不是b&b整数类型因此不适合size_t和

ptrdiff_t。


在长度与指针宽度相同的机器上

(更一般地说,没有比它们的指针宽一些),这意味着

ptrdiff_t不能足够宽以表达所有

指针减法的结果。一个简单的例子:


char * p = malloc(LONG_MAX + 2u); / *假设成功* /

char * q = p + LONG_MAX + 2u;

ptrdiff_t delta = q - p;


我们现在将p<但是(可能)delta< 0.


>如果是,那么MS
Win64实现不符合C89(虽然sizeof case可能是有争议的,我猜,我们当然可以要求malloc超过ULONG_MAX
字节,并获得需要超过(unsigned)
long的指针算术。如果不是,为什么这两段,如果依赖于长期足够大的程序已经被打破了?



我不知道MS的'Win64实现是否足以评论

是否已损坏。



它有32位长,与int相同,自然是64位size_t。


至于假设

size_t和ptrdiff_t的程序并不比很长,不是:它们不是根据C89规则打破的,因为C89暗示了真相。

假设。



然后这些程序可能会在Win64上被破坏,对吗?说,这段代码:


void do_something(void * buf,unsigned long len)

{

memset(buf,1 ,len);

}


int main(无效)

{

size_t i;

size_t size = BIG_NUMBER;

char * p = malloc(size);

if(p)

{

do_something(p,size);

断言(p [size-1]);

}

返回0;

}


BIG_NUMBER可以定义为SIZE_MAX + 1的某个平方根乘以两个或两个等等的
,所以我们不需要发明能够获得大缓冲的功能。我猜MS估计他们的代码有多少

使用long作为32位int,并且决定它不仅仅是使用

unsigned long作为size_t的代码。无论如何,MS Win64的实现不是符合C89标准的b $ b(这是一件很重要的事情,不是吗?)或者我确实想念

什么?


谢谢,

Yevgen


< blockquote> Yevgen Muntyan写于03/14/07 15:14,:


Eric Sosman写道:


>> Yevgen Muntyan写于03/14/07 14:26,:


>>> [...]
C89是否需要sizeof()的结果符合无符号长整数,
并且指针减法结果适合长? [...]
如果是,那么MS
Win64实现不符合C89(虽然sizeof case可能是有争议的,我想,我们当然可以向malloc请求超过ULONG_MAX
bytes,并获取需要超过(unsigned)
long的指针算术。 [...]


我不知道MS的Win64实现是否足以评论它是否被破坏。



它有32位长,与int相同,自然是64位size_t。



如果size_t宽于long,则实现不能符合C89的
。但是,它可以符合C99,

size_t可以长到很长或者是其他宽类型。

我要做的(很多)事情之一不知道MS Win64是什么
它声称要遵守的b $ b标准。


>> ;至于假设
size_t和ptrdiff_t不长于不长的程序,没有:根据C89的规则它们没有被打破,因为C89隐含了
假设的真实性。



然后这些程序可能会在Win64上被破坏,对吧?说,这段代码:


void do_something(void * buf,unsigned long len)

{

memset(buf,1 ,len);

}


int main(无效)

{

size_t i;

size_t size = BIG_NUMBER;

char * p = malloc(size);

if(p)

{

do_something(p,size);

断言(p [size-1]);

}

返回0;

}



如果malloc()成功,此程序在C89下工作,但

可能不适用于C99实现。


[...]无论如何,MS Win64实现不是

C89符合(它'''这是一件重要的事,不是吗?或者我确实想念

的东西?



从您的描述中,它不能是符合C89

的实现。这很重要吗?好吧,给谁?


-
Er *** ****** @ sun.com


Hey,

I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:

6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."

6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."

Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long? If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?

Yevgen

解决方案

Yevgen Muntyan wrote On 03/14/07 14:26,:

Hey,

I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:

6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."

6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."

Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long?

"Yes" and "Almost," respectively. C89 offered a fixed
set of integer types, of which {,un}signed long was the widest.
The implementation was free to provide additional types that
behaved like integers, but they were not "integer types" as
C89 defined them. C89 also required that size_t and ptrdiff_t
be aliases for "integer types," so they could not be wider than
long. If an implementation offered wider types, they were not
"integer types" and hence were not candidates for size_t and
ptrdiff_t.

On machines whose longs are the same width as their pointers
(more generally, no wider than their pointers), this means that
ptrdiff_t cannot be wide enough to express the result of all
pointer subtractions. An easy example:

char *p = malloc(LONG_MAX + 2u); /* assume success */
char *q = p + LONG_MAX + 2u;
ptrdiff_t delta = q - p;

We will now have p < q but (probably) delta < 0.

If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?

I don''t know MS'' Win64 implementation well enough to comment
on whether it''s broken or not. As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89''s rules, because C89 implied the truth of the
assumption. C99 changed the rules, allowing the implementation-
defined "exotic" types to be counted among the "integer types,"
and this change could break some programs that relied on the old
rule. Hence the "Quiet Change" warnings.

--
Er*********@sun.com


Eric Sosman wrote:

Yevgen Muntyan wrote On 03/14/07 14:26,:

>Hey,

I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:

6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."

6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."

Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long?


"Yes" and "Almost," respectively. C89 offered a fixed
set of integer types, of which {,un}signed long was the widest.
The implementation was free to provide additional types that
behaved like integers, but they were not "integer types" as
C89 defined them. C89 also required that size_t and ptrdiff_t
be aliases for "integer types," so they could not be wider than
long. If an implementation offered wider types, they were not
"integer types" and hence were not candidates for size_t and
ptrdiff_t.

On machines whose longs are the same width as their pointers
(more generally, no wider than their pointers), this means that
ptrdiff_t cannot be wide enough to express the result of all
pointer subtractions. An easy example:

char *p = malloc(LONG_MAX + 2u); /* assume success */
char *q = p + LONG_MAX + 2u;
ptrdiff_t delta = q - p;

We will now have p < q but (probably) delta < 0.

>If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?


I don''t know MS'' Win64 implementation well enough to comment
on whether it''s broken or not.

It has 32-bit long, same as int, and naturally 64-bit size_t.

As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89''s rules, because C89 implied the truth of the
assumption.

Then these programs may be broken on Win64, right? Say, this code:

void do_something (void *buf, unsigned long len)
{
memset (buf, 1, len);
}

int main (void)
{
size_t i;
size_t size = BIG_NUMBER;
char *p = malloc (size);
if (p)
{
do_something (p, size);
assert (p[size-1]);
}
return 0;
}

BIG_NUMBER can be defined as some square root of SIZE_MAX+1 multiplied
by two or something, so we don''t need to invent functions which get
us a big buffer. I guess MS estimated somehow how much of their code
uses long as 32-bit int, and decided it''s more than code which uses
unsigned long as size_t. Anyway, is MS Win64 implementation not
C89-conforming (it''s an important thing, isn''t it)? Or I do miss
something?

Thanks,
Yevgen


Yevgen Muntyan wrote On 03/14/07 15:14,:

Eric Sosman wrote:

>>Yevgen Muntyan wrote On 03/14/07 14:26,:

>>>[...]
Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long? [...]
If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). [...]


I don''t know MS'' Win64 implementation well enough to comment
on whether it''s broken or not.


It has 32-bit long, same as int, and naturally 64-bit size_t.

If size_t is wider than long, the implementation cannot
conform to C89. It could, however, conform to C99, with
size_t being as wide as long long or as some other wide type.
One of the (many) things I don''t know about MS Win64 is what
standards it claims to conform to.

>>As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89''s rules, because C89 implied the truth of the
assumption.


Then these programs may be broken on Win64, right? Say, this code:

void do_something (void *buf, unsigned long len)
{
memset (buf, 1, len);
}

int main (void)
{
size_t i;
size_t size = BIG_NUMBER;
char *p = malloc (size);
if (p)
{
do_something (p, size);
assert (p[size-1]);
}
return 0;
}

If malloc() succeeds, this program works under C89 but
might not work on a C99 implementation.

[...] Anyway, is MS Win64 implementation not
C89-conforming (it''s an important thing, isn''t it)? Or I do miss
something?

From your description, it cannot be a conforming C89
implementation. Is that important? Well, to whom?

--
Er*********@sun.com


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

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