【问题标题】:ERROR: Label "foo" used but not defined错误:标签“foo”已使用但未定义
【发布时间】:2013-05-31 07:45:02
【问题描述】:

所以我在玩一些 C++ 并得到了前面提到的错误,其中一些代码看起来像这样:

#include <iostream>
using namespace std;

char foodstuffs;

void fruit()
{
cin>>foodstuffs;
switch(foodstuffs)
{
case 'a': goto foo; break;
case 'b': goto fooo; break;
}
}

int main()
{
cout<<"What do you want to eat? (a/b)";
fruit();
foo: cout<<"You eat an apple.";
fooo: cout<<"You eat a banana.";
}

确切的代码要复杂得多,但这只是为了向您展示我遇到的错误。

现在我意识到,出于某种原因,每个人都鄙视“goto”语句,但我的实际代码中充满了太多的 goto,以至于我真的没有时间/耐心回去更改它们。另外,我是一个新手程序员,我发现 goto 和标签非常易于使用。

我的问题是如何预定义这些标签,以便函数 fruit() 知道它们是什么?另外,我需要在不将标签移出主要功能的情况下执行此操作。

【问题讨论】:

  • 您会发现 goto 和标签易于使用,但很难返回和更改。我的朋友,这就是为什么每个人都讨厌他们。
  • 为什么要转到?正如克里斯所说,每个人都讨厌他们;)
  • 重点是,您已经看到了它们如何使代码难以阅读、遵循、理解和维护。 goto 有几个有效的用途可以使代码更干净,如果生成的代码更干净,我个人不会惩罚 goto,但绝对不是一时兴起的东西。
  • @UrameshiYusuke 那是因为你不能那样做。你需要学会不使用goto来帮助自己。
  • 如果可以的话,我会否决所有不回答问题而是争论是否使用 goto 的人。这还不够:他们还否决了这个问题。您好:问题不在于使用 goto 好不好。

标签: c++ function label goto


【解决方案1】:

goto 语句只能跳转到本地定义的标签,不能跳转到其他函数。

所以main中的标签不会被引用,fruit中的goto语句也不会找到标签。

【讨论】:

  • 那我可以用什么跳转到其他功能呢?
  • @UrameshiYusuke 不要跳转到其他功能。只需返回呼叫点即可。
  • @UrameshiYusuke 我的建议是:不要!如果您需要在功能之间跳转,您的设计很可能存在缺陷。取而代之的是 return 来自具有特殊值的函数,然后在调用者的返回值上使用 ifswitch 来执行不同的操作。使用goto 在一些非常有限的情况下可能很有用,但对于大多数用途来说,总是有其他更好的解决方案。
【解决方案2】:

您正在尝试做的事情 - 在函数之间跳转 - 由于一系列原因(尤其是对象范围和生命周期)无效,请考虑:

void foo()
{
    if(feelLikeIt)
       goto foobar;
}

void bar()
{
    std::string message = "Hello";
foobar:
    cout << message << endl;
}

从 foo 跳转到 foobar 是非法的,因为“消息”将不存在。

所以简单的语言不允许你这样做。

此外,您尝试使用“goto”的方式会阻止您重新使用“fruit()”函数,因为它总是决定如何处理选择而不是调用它的函数。如果你想这样做怎么办:

cout<<"What do you want to eat? (a/b)";
fruit();
foo: cout<<"You eat an apple.";
fooo: cout<<"You eat a banana.";
cout<<"What does your friend want to eat? (a/b)";
fruit();
// oops, you just created a loop because fruit made the decision on what to do next.

您实际上想要做的是使用“fruit()”作为返回值的函数。

enum Fruit { NoSuchFruit, Apple, Banana };

Fruit fruit(const char* request)
{
    char foodstuffs;
    cout << request << " (a/b)";
    cin >> foodstuffs;
    switch (foodstuffs)
    {
        case 'a': return Apple;
        case 'b': return Banana;
        default:
            cout << "Don't recognize that fruit (" << foodstuffs << ")." << endl;
            return NoSuchFruit;
    }
}

const char* fruitNames[] = { "nothing", "an apple" ,"a banana" };

int main()
{
    Fruit eaten = fruit("What do you want to eat?");
    cout << "You ate " << fruitNames[eaten] << "." << endl;
    eaten = fruit("What does your friend want to eat?");
    cout << "Your friend ate " << fruitNames[eaten] << "." << endl;
}

【讨论】:

    【解决方案3】:

    对不起。您不能 goto 到当前执行函数之外的标签。此外,goto 的使用还有其他限制。例如,您不能使用goto 跳过变量定义。还有一些我不完全了解的。

    底线?

    不要使用goto

    【讨论】:

    • 我认为它在组装方面很好,并且可以很好地相似。
    • 问题不是要不要用而是怎么用。
    【解决方案4】:

    goto 不能用于在当前函数之外导航。尝试从函数中返回一些东西并在 if else 条件下使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2012-12-04
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多