Does this justify goto statements?

I came across this question a second ago, and I’m pulling some of the material off of there: Is there a name for the ‘break n’ construct?

This appears to be a needlessly complex way for people to have to instruct the program to break out of a double-nested for loop:

for (i = 0; i < 10; i++) {
    bool broken = false;
    for (j = 10; j > 0; j--) {
        if (j == i) {
            broken = true;
            break;
        }
    }
    if (broken)
        break;
}

I know textbooks like to say goto statements are the devil, and I’m not fond of them at all myself, but does this justify an exception to the rule?

I’m looking for answers that deal with n-nested for loops.

NOTE: Whether you answer yes, no, or somewhere in between, completely close-minded answers are not welcome. Especially if the answer is no, then provide a good, legitimate reason why (which is not too far from Stack Exchange regulations anyway).

6

The apparent need for a go-to statement arises from you choosing poor conditional expressions for the loops.

You state that you wanted the outer loop to continue as long i < 10 and the innermost one to continue as long as j > 0.

But in reality that’s not what you wanted, you simply didn’t tell the loops the real condition you wanted them to evaluate, then you want to solve it by using break or goto.

If you tell the loops your true intentions to begin with, then no need for breaks or goto.

bool alsoThis = true;
for (i = 0; i < 10 && alsoThis; i++)
{    
    for (j = 10; j > 0 && alsoThis; j--)
    {
        if (j == i)
        {
            alsoThis = false;
        }
    }
}

5

In this instance, you could refactor the code into a separate routine, and then just return from the inner loop. That would negate the need to break out of the outer loop:

bool isBroken() {
    for (i = 0; i < 10; i++)
        for (j = 10; j > 0; j--)
            if (j == i) return true;

    return false;
}

3

No, I don’t think a goto is necessary. If you write it like this:

bool broken = false;
saved_i = 0;
for (i = 0; i < 10 && !broken; i++)
{
    broken = false;
    for (j = 10; j > 0 && !broken; j--)
    {
        if (j == i)
        {
            broken = true;
            saved_i = i;
        }
    }
}

Having &&!broken on both loops lets you break out of both loops when i==j.

To me, this approach is preferable. The loop conditions are extremely clear: i<10 && !broken.

A working version can be seen here: http://rextester.com/KFMH48414

Code:

public static void main(String args[])
{
    int i=0;
    int j=0;
    boolean broken = false;
    for (i = 0; i < 10 && !broken; i++)
    {
        broken = false;
        for (j = 10; j > 0 && !broken; j--)
        {
            if (j == i)
            {
                broken = true;
                System.out.println("loop breaks when i==j=="+i);
            }
        }
    }
    System.out.println(i);
    System.out.println(j);
}

Output:

loop breaks when i==j==1
2
0

7

The short answer is “it depends”. I advocate to choose regarding legibility and understandability of your code. The goto way might be more legible than tweaking the condition, or vice versa. You might also take into account least surprise principle, guideline used in the shop/project and consistency of the code base. For instance, goto to leave switch or for error handling is a common practice in the Linux kernel code base. Also note that some programmers might have problems reading your code (either raised with the “goto is evil” mantra, or just not learned because their teacher think so) and a few of them might even “judge you”.

Generally speaking, a goto going further in the same function is often acceptable, especially if the jump is not too long. Your use case of leaving a nested loop is one of the known example of “not so evil” goto.

In your case, goto is enough of an improvement that it looks tempting, but it’s not so much of an improvement that it’s worth breaking the rule against using them in your code base.

Think of your future reviewer: s/he will have to think, “Is this person a bad coder or is this in fact a case where the goto was worth it? Let me take 5 minutes to decide this for myself or research it on the internet.” Why on earth would you do that to your future coder when you can not use goto entirely?

In general this mentality applies to all “bad” code and even defines it: if it works now, and is good in this case, but creates effort to verify it’s correct, which in this era a goto will always do, then don’t do it.

That being said, yes, you produced one of the slightly thornier cases. You may:

  • use more complex control structures, like a boolean flag, to break out of both loops
  • put your inside loop inside its own routine (likely ideal)
  • put both loops in a routine and return instead of breaking

It’s very hard for me to create a case where a double-loop isn’t so cohesive that it shouldn’t be its own routine anyway.

By the way, the best discussion of this I’ve seen is Steve McConnell’s Code Complete. If you enjoy thinking of these problems critically I strongly recommend reading, even cover-to-cover despite its immensity.

2

TLD;DR: No in specific, yes in general

For the specific example you used I would say no for the same reasons many other have pointed out. You can easily refactor the code into an equivalently good form which eliminates the need for the goto.

In general the proscription against goto is a generality based on the understood nature of goto and the cost of using it. Part of software engineering is making implementation decisions. Justification of those decisions occurs by weighing the cost against the benefits and whenever the benefits outweigh the cost the implementation is justified. Controversy arises because of different valuations, both of cost and benefit.

The point is there will always be exceptions where a goto is justified, but only for some because of different valuations. The pity is many engineers simply exclude techniques in purposeful ignorance because they read it on the internet rather than taking the time to understand why.

1

I don’t think this case justifies an exception, as this can be written as:

def outerLoop(){
    for (i = 0; i < 10; i++) {
        if( broken?(i) )
          return; // broken
    }
}

def broken?(i){
   for (j = 10; j > 0; j--) {
        if (j == i) {
            return true; // broken
        }
   }
   return false; // not broken
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật