3

My biggest problems are all stated above, the inability to jump to label fin (error on line 27), the error: from here (error on lines 12 and 14) and the crosses initialization error (error on line 20) Please help!

#include <iostream>
#include <string>

int main()
{
  std::string name;
  std::cout << "Please comply. y/n: ";
  std::string answer;
  std::cin >> answer;
  if (answer == "y"){std::cout << "You were spared." << std::endl; goto fin;}
  if (answer == "Miche"){std::cout << "The killers understood that you understood the prophecy, so they took you to their master" << std::endl; goto secret;}
  if (answer == "n"){std::cout << "You were brutally killed." << std::endl; goto fin;}
  else {std::cout << "You randomly babled " << answer << ", getting yourself killed."; goto fin;}
  secret:
  std::cout << "In order to fully find out if you are the legendary Miche, they took you to their leader."
  << " The master looked you over, and asked you one final question. The master asks you, fish?" << std::endl;

  std::string fish; fish = "none";
  std::cin >> fish;
  if (fish == "fish."){std::cout << "You were put in the throne of the king, where you ruled your near killers and their species for eternity."
  << std::endl; goto fin;}
  else {std::cout << "You failed and were immediately killed." << std::endl; goto fin;}
  goto fin;

  fin:

  return 0;
}
derekerdmann
  • 17,696
  • 11
  • 76
  • 110
Michael Erickson
  • 41
  • 1
  • 1
  • 4
  • we dont see the line numbers in you post. please remove irrelavant code and point to the place where the error occurs. – 463035818_is_not_an_ai Apr 12 '16 at 18:19
  • 8
    Protip: don't use goto; – Borgleader Apr 12 '16 at 18:21
  • 2
    There are cases when one would want to use `goto` but this is not it. You could use `std::exit` or just a `return 0;` – NathanOliver Apr 12 '16 at 18:21
  • No, your biggest problem is that you are using `goto`. – SergeyA Apr 12 '16 at 18:21
  • 1
    @NathanOliver, I would really love to see a justified case for `goto` in C++ program. If you post one as the answer, I will personally upvote it (provided it is justified, of course!) – SergeyA Apr 12 '16 at 18:22
  • And put your if statement on multiple line. This just makes it hard to read. – Ceros Apr 12 '16 at 18:23
  • Your problem is here : std::string fish; fish = "none"; declare fish at the beginning of your function. goto fin; – willll Apr 12 '16 at 18:25
  • @SergeyA [this](http://stackoverflow.com/a/3517765/4342498) really is what I think of for an acceptable way to use `goto`. Without it breaking out of multiple nested loops becomes verbose. – NathanOliver Apr 12 '16 at 18:27
  • you can search about programming without goto – Shakiba Moshiri Apr 12 '16 at 18:30
  • 2
    @NathanOliver, yeah, was kinda expecting this. But proper refactoring (like putting a loop into another function and returning from it) usually yield better results. Some people advocate for `throw`ing your way out of loops, but I am not in favor that. – SergeyA Apr 12 '16 at 18:30
  • Relevant: [error: jump to label 'foo' crosses initialization of 'bar'](http://stackoverflow.com/q/31513798/253056). – Paul R Apr 12 '16 at 18:35
  • @SergeyA Good point. I don't think I have ever used `goto` in a program and I try to not even use `break` and `continue`. – NathanOliver Apr 12 '16 at 18:40
  • You end up using `goto cleanup;` in programs that use C APIs and dynamically allocated memory. Rather than have repetitive cleanup after checking the return code from every C call, if one of them fails, just say `goto cleanup`. It's old school code for to avoid memory leaks when using old school APIs. My current example: OpenSSL. It happens. – Charlie Reitzel Mar 23 '23 at 23:13

2 Answers2

5

The problem is, essentially this:

int main() {
    if (whatever)
        goto fin;
    std::string fish;
fin:
    return 0;
}

If whatever is true, the goto jumps past the construction of fish. That's not allowed, because the compiler can't generate sensible code to destroy fish or not, depending on whether the goto was executed.

Solution: don't use goto.

Possibilities:

int main() {
    if (whatever)
        goto fin;
    {
    std::string fish;
    }
fin:
    return 0;

Here, fish gets destroyed at the end of the block, so the goto doesn't cause a problem (aside from its inherent unstructured nature).

Better:

int main() {
    if (!whatever) {
        std::string fish;
    }
    return 0;
}
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
2

You can duplicate the problem using a much simpler function.

void foo()
{
   goto fin;
   std::string fish = "none";
   std::cin >> fish;

   fin:
}

Why is that a problem? When the execution jumps to fin:, the code to initialize fish is not executed. Its destructor will be called when the function returns. Since the destructor will be called on an uninitialized object, the program will exhibit undefined behavior.

The simplest fix for your problem is to put almost everything in main in another function, and then use return instead of goto.

void do_stuff()
{
   std::string name;
   std::cout << "Please comply. y/n: ";
   std::string answer;
   std::cin >> answer;

   if (answer == "y")
   {
      std::cout << "You were spared." << std::endl;
      return;
   }
   if (answer == "n")
   {
      std::cout << "You were brutally killed." << std::endl;
      return;
   }

   if (answer == "Miche")
   {
      std::cout << "The killers understood that you understood the prophecy, so they took you to their master" << std::endl;
   }
   else
   {
      std::cout << "You randomly babled " << answer << ", getting yourself killed.";
      return;
   }

   std::cout << "In order to fully find out if you are the legendary Miche, they took you to their leader."
      << " The master looked you over, and asked you one final question. The master asks you, fish?" << std::endl;

   std::string fish = "none";
   std::cin >> fish;
   if (fish == "fish")
   {
      std::cout << "You were put in the throne of the king, where you ruled your near killers and their species for eternity." << std::endl;
   }
   else
   {
      std::cout << "You failed and were immediately killed." << std::endl;
   }
}

int main()
{
   do_stuff();
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270