Nothing is wrong with goto if it is used properly. The reason it is "taboo" is because in the early days of C, programmers (often coming from an assembly background) would use goto to create incredibly hard-to-understand code.
Most of the time, you can live without goto and be fine. There are a few instances, however, where goto can be useful. The prime example is a case like:
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
...
if (condition)
goto break_out;
....
}
}
}
break_out:
Using a goto to jump out of a deeply-nested loop can often be cleaner than using a condition variable and checking it on every level.
Using goto to implement subroutines is the main way it is abused. This creates so-called "spaghetti code" that is unnecessarily difficult to read and maintain. goto can also be used to jump from one function into another without making a function call, but this is almost always dangerous and disastrous.