goto 的一点小问题

[复制链接]
5614|13
 楼主| fzu_csc 发表于 2010-9-18 11:07 | 显示全部楼层 |阅读模式
首先,goto当然最好不用,但在跳出深度循环方面还是可以简化问题的,只要没有因此跳过变量初始化之类的,应该没问题。 批判goto,可以先存异。

截程序中一小段代码:
I2C_INIT:
pI2C_InitVal();

I2C_START:
switch(bI2C_Status)
{

编译结果:
I2C_SLAVE.C(64):WARNING C280: 'I2C_START': unreferenced label
I2C_SLAVE.C(137):ERROR C233: 'I2C_START': undefined label

一个提示的是标签未被引用,一个提示的是标签未定义,是不是相互矛盾了??
而且,同样的标签I2C_INIT怎么不存在这个问题?
冷漠 发表于 2010-9-18 13:05 | 显示全部楼层
本帖最后由 冷漠 于 2010-9-18 13:08 编辑

呵,只有用错了goto语句时,才可能出现这样的编译结果。因为对于goto语句来说,它没有找到I2C_START 标号地址!goto 何方?  对茫然的编译器来说,当然就是既没有定义,又没有引用……

还是认真检查自己的问题为好,批判goto?还没人做过这件事。LZ抓住灵感写篇论文可以做业界第一。目标、机会来了。顶你。
xwj 发表于 2010-9-18 13:28 | 显示全部楼层
汗~

LZ连C语言基本的语法和作用域都不懂,就来批判这个批判哪个了?
 楼主| fzu_csc 发表于 2010-9-18 14:17 | 显示全部楼层
3# xwj

我不批判的呀...我就怕大家不看我的问题一看用goto出了问题就让我不用goto了事。

作用域的话,goto难道只能goto到同一个函数的标号,应该不是如此,那就太局限了,总不至于还有声明标号这说法吧? 为什么同样的情况下,I2C_INIT不存在此问题?

愿闻其详,谢谢。
 楼主| fzu_csc 发表于 2010-9-18 14:25 | 显示全部楼层
I2C_INIT 不存在此问题有可能还未编译到。
 楼主| fzu_csc 发表于 2010-9-18 14:30 | 显示全部楼层
3# xwj

好的,谢谢,果然不能跳出函数体外。

我猜测呢,跳出函数体外,堆栈确实会错乱掉....非不想,实不能导致。

谢谢!
ntao0227 发表于 2010-9-18 16:31 | 显示全部楼层
下面是,林锐在《C语言深度解剖》中的一段:
一般来说,编码的水平与goto 语句使用的次数成反比。有的人主张慎用但不禁用goto
语句,但我主张禁用。关于goto 语句的更多讨论可以参看Steve McConnell 的名著《Code
Complete. Second Edition》。
【规则1-32】禁用goto 语句。
自从提倡结构化设计以来,goto 就成了有争议的语句。首先,由于goto 语句可以灵活
跳转,如果不加限制,它的确会破坏结构化设计风格;其次,goto 语句经常带来错误或隐
患。它可能跳过了变量的初始化、重要的计算等语句,例如:
struct student *p = NULL;

goto state;
p = (struct student *)malloc(…); //被goto 跳过,没有初始化

state:
//使用p 指向的内存里的值的代码

如果编译器不能发觉此类错误,每用一次goto 语句都可能留下隐患。
 楼主| fzu_csc 发表于 2010-9-19 08:13 | 显示全部楼层
7# ntao0227

确实,尽量不用,但如果是深度循环的话,一般比如跳到出错处理,不用goto又要设信号量又得一层一层break跳出来甚是麻烦,此时goto,并且做一下注释,不大应该会出问题。其它没发现需要用到的地方。

不过从安全考虑,一个函数的循环最好也不能太多层。

禁用goto,是出于安全规范的考虑,用不用就仁者见仁,智者见智了。

刚买的一本书《C陷阱和缺陷》里,刚开始看,作者就有此一比,怎样才能让菜刀切不到手?
mohanwei 发表于 2010-9-19 08:50 | 显示全部楼层
瞎扯,按照那样的理论,switch-case最好也禁用,因为case可能会漏考虑了“变量的初始化、重要的计算等语句,例如:……”
if-else最好也要禁用,因为可能条件有多个的时候会少输入几组else if……
sz_longyue 发表于 2010-9-19 09:33 | 显示全部楼层
一般好的结构很少会出现深度循环,更不会出现需要用GOTO来跳出深度循环的情况
如果出现了这样的情况,你该反思一下你自己的代码
 楼主| fzu_csc 发表于 2010-9-19 10:34 | 显示全部楼层
《C陷阱与缺陷》原话:使其难于做“傻事”常常会使其难于做“聪明事”,正所谓“弄巧成拙”。

没有绝对的好和坏,取个平衡吧。
Galway-Zhang 发表于 2010-9-29 17:03 | 显示全部楼层
goto很方便呀.

直接想跳到哪就哪

与ASM的jmp

都简单些.
孤傲雕 发表于 2010-9-29 21:58 | 显示全部楼层
goto有一定的局限性,它在一定程度上可以代替for但是一般都不这么用!!我的观点是能不用就不用!!
ejack 发表于 2010-9-30 07:52 | 显示全部楼层
个人觉得程序尽量不要干涉到汇编层面,因为这样会影响程序的通用性,给今后的维护以及移交都带来了很大的困难。goto在大多数情况下通过状态标志都是可以处理掉的,效率微微降低。
当然如果有人认为“这程序是我写的,是我的,我的!移交给别人时,一定要拖累他调上半个月”,那我也无话可说了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

142

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部