I  seen a parade of misinformed "instructors" warning me to not use a certian part of a language because its "dangerous," or hard to understand.  The maligned programming contexts include everything from pointers, to the ?: operator but especialy GOTOs.  In most cases this advice originates not from the properties of the language but the ignorance of the advisor.

Skilled programming in any language means knowing all the properties of all the constructs, and also knowing the common semantic implications of those constructs.  It is pure lunacy to avoid portions of a language merely because someone else might not understand the full language.

Thus, it seems that all programmers know that too many GOTOs can lead to confusing, unmaintainable code.  What it seems fewer programmers understand is tha occasionally a well placed goto can significantly simplify an algorithm, especially in deeply nested loops with middle exit points.  The construct is not good or bad, it just had good and bad properties and can be easily misused.  This is why gotos continue to be included in modern languages like C# and java even though their negative properties have been known for decades.

I have a bigger problem with the "well I'll just synthesize a goto with a try block argument."  Perf concerns aside, this construct says the wrong thing.  Exceptions semantically mean error handling, and using exceptions for control flow is going to confuse people becuase it is using a construct for the wrong thing.  Its like using:

int i = 0;
while (i < 10) {
// do something
 i++
}

instead of
for (int i = 0; i < 10; i++){
  // do something
}

because someone told you that for statements are confusing.  (And they are until someone explains them.)

I use unrestricted gotos very rarely, less than once a year.  But to write any language element off as "bad" without reference to context or usage is just intellectual laziness