使用转到跳过变量声明? [英] Skip variable declaration using goto?

查看:124
本文介绍了使用转到跳过变量声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读的 C语言程序设计 - 一种现代方法的由KNKing学习C语言编程,并有人指出,转到语句不能跳变长数组声明。

但现在的问题是:为什么转到跳允许跳过固定长度的数组声明和普通声明?更precisely,什么是象这些例子的行为,根据C99标准?当我测试了这些情况下,它似乎像的声明实际上没有跳过去,但是是正确的?是的声明可能已经跃过安全变量使用?

1

 转到更高版本;
int类型的= 4;
后来:
的printf(%d个,一);

2

 转到更高版本;
int类型的;
后来:
一个= 4;
的printf(%d个,一);

3。

 转到更高版本;
诠释一个[4];
一个[0] = 1;
后来:
一个[1] = 2;
对(INT I = 0; I&下;的sizeof(一)/的sizeof(一个[0]);我+ +)
  的printf(%d个\\ N,一个[我]);


解决方案

我的心情很为这个解释没有血淋淋的内存布局的详细信息(相信我,他们得到的非常的血腥沃拉斯时有使用;见@ Ulfalizer的回答了解详细信息)

所以,最初,在C89,这是强制性的在块的开始宣告所有的变量,像这样的:

  {
    INT A = 1;
    一个++;
    / * ... * /
}

这直接说明了一个非常重要的事情:一个块== 1不变组变量声明

C99改变了这种。在这里面,你可以在块的任何部分声明变量,但声明语句仍然经常陈述不同。

事实上,要明白这一点,你可以想像,所有的变量声明是隐移动到他们的声明和不可用的所有语句preceed他们块的开始。

这很简单,因为声明的一个块==一组的规则仍然有效。

这就是为什么你不能跳过宣言。该声明的变量仍然存在。

问题是初始化。它没有得到感动的任何地方。因此,技术上,对于你的情况,以下为节目可以被视为等同的:

 转到更高版本;
int类型的= 100;
后来:
的printf(%d个,一);

  int类型的;
转到更高版本;
一个= 100;
后来:
的printf(%d个,一);

正如你所看到的,声明仍然存在,被忽略的是初始化。

这并不沃拉斯工作的原因是,他们是不同的。总之,这是因为这是有效的:

  int长度= 7;
INT测试【规格】;

沃拉斯的声明将与所有其他声明,不同的行为在声明它们的块的不同部分。事实上,VLA可能有完全不同的内存布局取决于它的声明。你就不能动它,你刚刚翻过的地方之外。

您可能会问,没事,那为什么不把它,这样的声明是由转到未受影响?那么,你仍然会得到情况是这样的:

 转到更高版本;
INT大小= 7;
INT测试【规格】;
后来:

你有什么实际期望这做什么?..

所以,禁止跳跃过VLA声明是有原因的 - 它是通过简单地完全禁止他们像上述案件时最合乎逻辑的决定。

I am reading C Programming - A Modern Approach by K.N.King to learn the C programming language and it was noted that goto statements must not skip variable-length array declarations.

But now the question is: Why are goto jumps allowed to skip fixed-length array declarations and ordinary declarations? And more precisely, what is the behavior of examples like these, according to the C99 standard? When I tested these cases it seemed like the declarations were actually not jumped over, but is that correct? Are the variables whose declarations might have been jumped over safe to use?

1.

goto later;
int a = 4;
later:
printf("%d", a);

2.

goto later;
int a;
later:
a = 4;
printf("%d", a);

3.

goto later;
int a[4];
a[0] = 1;
later:
a[1] = 2;
for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
  printf("%d\n", a[i]);

解决方案

I'm in the mood for explaining this without gory memory-layout details (believe me, they get very gory when VLAs are used; see @Ulfalizer's answer for details).

So, originally, in C89, it was mandatory to declare all variables at the start of a block, like this:

{
    int a = 1;
    a++;
    /* ... */
}

This directly implies a very important thing: one block == one unchanging set of variable declarations.

C99 changed this. In it, you can declare variables in any part of the block, but declaration statements are still different from regular statements.

In fact, to understand this, you can imagine that all variable declarations are implicitly moved to the start of the block where they are declared and made unavailable for all statements that preceed them.

That is simply because the one block == one set of declarations rule still holds.

That is why you cannot "jump over a declaration". The declared variable would still exist.

The problem is initialization. It doesn't get "moved" anywhere. So, technically, for your case, the following programs could be considered equivalent:

goto later;
int a = 100;
later:
printf("%d", a);

and

int a;
goto later;
a = 100;
later:
printf("%d", a);

As you can see, the declaration is still there, what is being skipped is initialization.

The reason this doesn't work with VLAs is that they're different. In short, it's because this is valid:

int size = 7;
int test[size];

The declarations of VLAs will, unlike all other declarations, behave differently in different parts of the block where they are declared. In fact, a VLA might have entirely different memory layouts depending on where it is declared. You just can't "move" it outside of the place you just jumped over.

You may ask, "all right, then why not make it so that the declaration would be unaffected by the goto"? Well, you'd still get cases like this:

goto later;
int size = 7;
int test[size];
later:

What do you actually expect this to do?..

So, prohibiting jumping over VLA declarations is there for a reason - it is the most logical decision for dealing with cases like the above by simply prohibiting them altogether.

这篇关于使用转到跳过变量声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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