if/else, for, while, do/while are all syntactic sugar over top of goto. why do we use them instead of goto? because they're the right tool for the job. there are definitely cases where goto is the right solution. but I don't believe that breaking from a nested loop is one of them.
I don't even know why we still have threads on this subject. I'm certain that over the 40 years or so that the C language has been around, every opinion that can be offered on the subject has been heard, and either accepted as truth or rejected as folly.
in C, it's not an issue, but in C++, using goto can seriously alter program behavior, because you can jump over the initialization of a user-defined-type object, and then go on to use it as if it were initialized properly. most compilers will warn about this when you try it, but it can cause very strange behavior at times, up to, and including crashes. the behavior of a program under those conditions is undefined, and as with all undefined behavior, it is best to avoid it at all costs.