可变长度数组 [英] Variable length arrays

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

问题描述



如果VLA出现在循环体内,那么我尝试使用两个不同的编译器,行为似乎与b $ b不同。我查看了

标准文本,但在那里找不到明确答案。


考虑以下测试程序


/ * begin foo.c * /

#include< stdio.h>

#include< string.h>


void test(int n,size_t size)

{

int i;


for (i = 0; i< n; i ++){

unsigned char vla [size];

memset(vla,(i& 255),size);

printf(" step%d:vla =%p \ n",i,& vla [0]);

}

}


int main(无效)

{

test(10,256 * 1024L);

返回0;

}

/ * end foo.c * /


使用gcc,''vla ''在每次迭代中重复使用,即''vla [0]''的地址

在每一步都是相同的。


但是, lcc-win32,输出如下......


步骤0:vla = 0x002ffea0

步骤1:vla = 0x002bfea0

步骤2:vla = 0x0027fea0

步骤3:vla = 0x0023fea0

[* CRASH *]


,意思是,每次迭代都会为vla分配新的存储空间,

最终耗尽所有可用的自动存储空间。


现在,这只是依赖于实现和这种构造

应该避免,或者这些编译器之一是否工作不正常?


是否应该提交错误报告?


谢谢

-

Erwin Lindemann

解决方案

< blockquote> On Thu,2008年3月6日02:38:17 +0100(CET),Erwin Lindemann

< el ****** @ wupp.invalidwrote in comp.lang.c:


>

如果VLA出现在一个循环体内,那么行为似乎是两个不同的b $ b我试过不同的编译器。我查看了

标准文本,但也找不到明确的答案。



没有确定的答案。关于可能与b $ b相关的VLA的所有标准都是这样的:


"对于这样一个具有可变长度数组类型的对象,它的

life从对象的声明扩展到执行

程序离开声明的范围。如果范围是递归输入的
,则每个

时间创建一个新的对象实例。对象的初始值是不确定的。


它没有说明每个创作是否必须,可能或可能

不具有相同的内容地址。所以这完全是一个QOI问题。


考虑以下测试程序


/ * begin foo.c * /

#include< stdio.h>

#include< string.h>


void test(int n,size_t尺寸)

{

int i;


for(i = 0; i< n; i ++){

unsigned char vla [size];

memset(vla,(i& 255),size);

printf(" step%d :vla =%p \ n",i,& vla [0]);

}

}


int main(void)

{

test(10,256 * 1024L);

返回0;

} $ / $
/ * end foo.c * /


使用gcc,''vla''在每次迭代中重复使用,即地址
$'b $''vla [0]''在每一步都是相同的。


但是,使用lcc-win32,输出如下......


步骤0:vla = 0x002ffea0

步骤1:vla = 0x002bfea0

步骤2:vla = 0x0027fea0

步骤3:vla = 0x0023fea0

[* CRASH *]


,意思是,新存储分配给'' vla''在每次迭代时,

最终耗尽所有可用的自动存储空间。


现在,这只是依赖于实现的这种构造
应该避免
,或者这些编译器之一是否工作不正常?



由于标准不要求任何一种行为,因此我看不到它是一个
一致性缺陷。这是一个QOI问题,我建议您直接联系违规编译器的实施者,或者在他的支持小组上联系


是否应提交错误报告?



由于标准不保证自动持续时间的任何数组的创建都会成功,即使它不是VLA,很难

看到有关标准一致性的投诉,但这是一个巨大的

QOI问题。


如果我使用了他编译器的这个功能,我会抱怨,虽然我已经完成了他并且不再使用他的编译器了。


考虑类似的情况:


#include< stdio.h>


void func(int x)

{

printf("%p \ n",(void *)& x;

}


int main(无效)

{

int x = 0;

func();

func ();

func();

返回x;

}


我不喜欢我想我曾经使用过一个实现,其中三个调用

到func()会输出不同的值。


你认为C标准要求它是一样的吗?如果没有,你认为应该这么做吗?


-

Jack Klein

http://JK-Technology.Com

常见问题解答

comp.lang.c http://c-faq.com/

comp.lang.c ++ http://www.parashift.com/c++-faq-lite/

alt.comp.lang.learn.c-c ++
http://www.club.cc.cmu.edu/~ajo /docs/FAQ-acllc.html


Erwin Lindemann< el ****** @ wupp.invalidwrites:


使用gcc,''vla''在每次迭代中重复使用,即''vla [0]''的地址

在每一步都是相同的。


但是,使用lcc-win32,输出如下...


步骤0:vla = 0x002ffea0

步骤1:vla = 0x002bfea0

步骤2:vla = 0x0027fea0

步骤3:vla = 0x0023fea0

[* CRASH *]


,意思是,每次迭代都会为vla分配新存储空间,<
最终耗尽了所有可用的自动存储空间。


现在,这只是依赖于实现的,应该避免使用这种构造

,或者这些编译器之一是否工作不正常?


是否应提交错误报告?



我会把它归档,是的。


6.2.4#6:

这样的对象 确实有

对于[具有自动存储持续时间的对象] [有]变量

长度数组类型,其生命周期从
对象,直到程序的执行离开

声明的范围。


-

Micah J. Cowan

程序员,音乐家,排版爱好者,游戏玩家......
http://micah.cowan.name/


Jack Klein写道:


>

如果我使用他的编译器的这个功能,我会抱怨,虽然我已经把他的b $给了他并且不再使用他的编译器了。


考虑一个类似的案例:


#include< stdio.h>


void func(int x)

{

printf("%p\ n",(void *)& x); //缺少")"固定

}


int main(无效)

{

int x = 0;

func();

func();

func();

返回x;

}


我不认为我曾经使用过一个实现,其中三个调用

到func()将输出不同的值。


你认为C标准要求它是一样的吗?如果没有,那么你认为应该这么做吗?



我很高兴你不使用我的编译系统,因为你的

有缺陷的代码甚至无法编译:


错误tbb.c:11'func'的参数数量不足

错误tbb.c: 12func的参数数量不足

错误tbb.c:13func的参数数量不足

3个错误,0个警告


-

jacob navia

jacob at jacob point remcomp point fr

logiciels / informatique
http://www.cs.virginia.edu/~lcc-win32



If a VLA appears within a loop body, it seems the behavior is
different with two different compilers I tried. I looked at the
standard text, but couldn''t find a definite answer there either.

Consider the following test program

/* begin foo.c */
#include <stdio.h>
#include <string.h>

void test(int n, size_t size)
{
int i;

for(i = 0; i < n; i++) {
unsigned char vla[size];
memset(vla, (i & 255), size);
printf("step %d: vla=%p\n", i, &vla[0]);
}
}

int main(void)
{
test(10, 256*1024L);
return 0;
}
/* end foo.c */

With gcc, ''vla'' is reused in every iteration, i.e., the address
of ''vla[0]'' is identical in every step.

However, with lcc-win32, output is as follows...

step 0: vla=0x002ffea0
step 1: vla=0x002bfea0
step 2: vla=0x0027fea0
step 3: vla=0x0023fea0
[*CRASH*]

, meaning, new storage is allocated for ''vla'' at every iteration,
eventually exhausting all available auto storage.

Now, is this just implementation dependant and this kind of construct
should be avoided, or is one of these compilers not working correctly?

Should a bug report be filed?

Thanks
--
Erwin Lindemann

解决方案

On Thu, 6 Mar 2008 02:38:17 +0100 (CET), Erwin Lindemann
<el******@wupp.invalidwrote in comp.lang.c:

>
If a VLA appears within a loop body, it seems the behavior is
different with two different compilers I tried. I looked at the
standard text, but couldn''t find a definite answer there either.

There is no definitive answer. All the standard says about VLAs that
might be relevant is this:

"For such an object that does have a variable length array type, its
lifetime extends from the declaration of the object until execution of
the program leaves the scope of the declaration. If the scope is
entered recursively, a new instance of the object is created each
time. The initial value of the object is indeterminate."

It says nothing at all about whether each creation must, may, or may
not have the same address. So it is entirely a QOI issue.

Consider the following test program

/* begin foo.c */
#include <stdio.h>
#include <string.h>

void test(int n, size_t size)
{
int i;

for(i = 0; i < n; i++) {
unsigned char vla[size];
memset(vla, (i & 255), size);
printf("step %d: vla=%p\n", i, &vla[0]);
}
}

int main(void)
{
test(10, 256*1024L);
return 0;
}
/* end foo.c */

With gcc, ''vla'' is reused in every iteration, i.e., the address
of ''vla[0]'' is identical in every step.

However, with lcc-win32, output is as follows...

step 0: vla=0x002ffea0
step 1: vla=0x002bfea0
step 2: vla=0x0027fea0
step 3: vla=0x0023fea0
[*CRASH*]

, meaning, new storage is allocated for ''vla'' at every iteration,
eventually exhausting all available auto storage.

Now, is this just implementation dependant and this kind of construct
should be avoided, or is one of these compilers not working correctly?

Since the standard does not require either behavior, it is not a
conformance defect that I can see. It is a QOI issue, and I suggest
you contact the offending compiler''s implementer, either directly or
on his support group.

Should a bug report be filed?

Since the standard does not guarantee that the creation of any array
of automatic duration will succeed, even if it is not a VLA, it''s hard
to see a complaint on standard conformance grounds, but it''s a huge
QOI issue.

I''d complain if I used this feature of his compiler, although I have
plonked him and don''t use his compiler at all anymore.

Consider a similar case:

#include <stdio.h>

void func(int x)
{
printf("%p\n", (void *)&x;
}

int main(void)
{
int x = 0;
func();
func();
func();
return x;
}

I don''t think I have ever used an implementation where the three calls
to func() would output different values.

Do you think the C standard requires it to be the same? If not, do
you think it should?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html


Erwin Lindemann <el******@wupp.invalidwrites:

With gcc, ''vla'' is reused in every iteration, i.e., the address
of ''vla[0]'' is identical in every step.

However, with lcc-win32, output is as follows...

step 0: vla=0x002ffea0
step 1: vla=0x002bfea0
step 2: vla=0x0027fea0
step 3: vla=0x0023fea0
[*CRASH*]

, meaning, new storage is allocated for ''vla'' at every iteration,
eventually exhausting all available auto storage.

Now, is this just implementation dependant and this kind of construct
should be avoided, or is one of these compilers not working correctly?

Should a bug report be filed?

I''d file it, yeah.

6.2.4#6:

"such an object" "does have"
For [an object with automatic storage duration] that [has] a variable
length array type, its lifetime extends from the declaration of the
object until execution of the program leaves the scope of the
declaration.

--
Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
http://micah.cowan.name/


Jack Klein wrote:

>
I''d complain if I used this feature of his compiler, although I have
plonked him and don''t use his compiler at all anymore.

Consider a similar case:

#include <stdio.h>

void func(int x)
{
printf("%p\n", (void *)&x); // missing ")" fixed
}

int main(void)
{
int x = 0;
func();
func();
func();
return x;
}

I don''t think I have ever used an implementation where the three calls
to func() would output different values.

Do you think the C standard requires it to be the same? If not, do
you think it should?

I am happy you do not use my compiler system since your
buggy code will not even compile:

Error tbb.c: 11 insufficient number of arguments to `func''
Error tbb.c: 12 insufficient number of arguments to `func''
Error tbb.c: 13 insufficient number of arguments to `func''
3 errors, 0 warnings

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32


这篇关于可变长度数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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