What about goto?
Albin Engström

I have a clouded memory of people saying "goto shouldn't be used", but i can think of alot of places when i want to use it, so please tell me what you think||know about "goto".

Matthew Leverton
Thomas Fjellstrom

goto can be very evil.

However it does have a few good uses. I can think of two right off the bat:

  • Error handling in large C functions.

  • Computed "goto" dispatch in a Virtual Machine's core.

edit: See the link in matthew's post ;)

Paul whoknows
Quote:

so please tell me what you think||know about "goto".

You don't need it, if you know how to use these instructions properly: do-while, switch, if-else.
Goto is ok for Basic programmers, but in C/C++ you have better and more elegant alternatives.
I have never used a goto in my C/C++ projects, and I will never do it.

Albin Engström

Understood, thank you :)

torhu

Use goto when it makes your code clearer. It's often used where you would use catch and finally blocks in java, ie. for jumping to some error cleanup code at the end of a function. And sometimes it's the cleanest way of breaking out of nested loops. But if you're using it to jump backwards, you better make sure there really isn't a better way. I've seen some messy code doing backwards jumps.

Bruce Perry
Quote:

Goto is ok for Basic programmers, but in C/C++ you have better and more elegant alternatives.

Are there really versions of BASIC that don't have proper looping constructs? BBC BASIC has REPEAT...UNTIL, FOR...NEXT and IF...ELSE. (OK, come to think of it, it doesn't have multi-line IF. Hmm.) There's no SWITCH but you can do that using IFs (and C's 'switch' is little more than gotos anyway, considering the way it falls through).

Incidentally, Java has a very good answer to 'goto'. It lets you label any statement (including loop statements that contain lots of nested statements), and then any nested statement can be a 'break' with that label - or a 'continue' if the labelled statement is a loop. It means you can break out of arbitrarily nested loops and jump to the next statement afterwards, and it keeps your code well-structured. You do indeed end up with no way to jump back without using a loop.

In C and C++, I'd have no problem with using a 'goto' to simulate that.

I have also used 'goto' to jump back though. I did that when the code wouldn't normally loop but there was just one specific case where I wanted it to repeat the body of the function. Sometimes it's a bit counter-intuitive to see a 'while' loop when it's not obvious why the code is going to loop. It's arguable though.

nonnus29

BP's right; the break and continue keywords are actually controlled goto's.

I think historically goto got a bad rap from back in the fortran/cobol days when that was all they had; Fortran didn't have if/then/else for a LONG time. Cobols paragraph structure is a sort of controlled procedure branching construct that goto would desrupt. If you goto'd/jumped out of a paragraph, the pgm would execute straight thru to the end. Then in the early MS basics like that on the c-64 all you had was goto and gosub.

In the 60's some guys proved that any flowchart could be implemented using only if/then/else and a pre-test loop like while(){}. That's one thing that led to the 'structured programming' revolution. It's hard to believe that something we take for granted and seems so obvious was revolutionary at one time.

Bruce Perry
Quote:

Then in the early MS basics like that on the c-64 all you had was goto and gosub.

Lame! The BBC Micro predated the C64, by about four years I believe.

ReyBrujo

Goto is the way you handle exceptions in Visual Basic.

Thomas Fjellstrom

Perl has some interesting semantics with labels and goto...

heres a nice quote from the man himself:

Larry Wall said:

If I allowed "next $label" then I'd also have to allow "goto $label", and I don't think you really want that... :-)

you can label a loop, and "next/last" on them, as if they were named loops. its rather handy.

FOO:
while(...) {
   BAR: for(...) { ... next FOO if $blah; next BAR if $baz; ... }
}

Bob

Goto is the buldozer of coding. Sometimes, the buldozer is just the right tool for the job. Not often, but sometimes.

Thomas Fjellstrom
Quote:

Goto is the buldozer of coding. Sometimes, the buldozer is just the right tool for the job. Not often, but sometimes.

Sigged for posterity.

Johan Halmén

"Why does a dog lick its penis?"
"Because it can."

I think goto is the most strange thing in C/C++. We all know it belongs to BASIC. We also know that it is a part of the standard C/C++. But I bet it is the only thing coders find strange, something that doesn't match the way of thinking and way of using the language.

I speak a kind of old Swedish (because I live in Finland), which is not influenced by English in same extent than the Swedish spoken in Sweden. It strikes me every time I see or hear a new English word in Swedish printed or spoken in Sweden, used as if it were a part of the language. But not only words. Some structures in sentences are also adapted from English. I find it horrible. A bit like using goto in C/C++.

orz
Quote:

But I bet it is the only thing coders find strange, something that doesn't match the way of thinking and way of using the language.

What about trigraphs? And macros. And the way ">>" is treated when terminating nested template parameters. And the way variable initializations are sometimes treated as function declarations. And...

Well, really, I agree with the point that goto is conceptually closer kin to asm or basic and is out of place in C and even farther from the intended paradigm of C++. I'm just saying that there's a bunch of other very strange stuff that somehow made it in to C++ too.

Johan Halmén

Ok, you might be right, there are more oddities than goto. I never knew about trigraphs. I bet they go way back to the time when all computers used 7 bit ascii for everything. I have my Bondwell 16 in my attic (next to my Sinclair ZX81). It used 7 bit ascii and to be able to show scandinavian letters Å, Ä and Ö, it replaced [ \ ] with Ä Ö Å. On a very low system level. It was burnt into the 128k bios ROM.

I didn't code in C at that time, but I coded in Pascal. And instead of writing FooÄ16Å, I wrote Foo(. 16 .)

On a standard English/US machine that would be Foo[16]

Neil Black
if(Bad == true)
         goto Hell;

Hell:
   Death = true;
   Burn = true;
   Pain = true;

ImLeftFooted
Possumdude0 said:

if(Bad == true)
         goto Hell;

Hell:
   Death = true;
   Burn = true;
   Pain = true;

So we're all going to hell no matter what? :'(

ReyBrujo

Of course!

Rampage

No, only if Bad == true

ReyBrujo

But if Bad is not true, you fall back to the same place!

Rampage

Oops, how could I miss that? I'll blame it on almost never using goto. Yes, that was it...

Bruce Perry
Quote:

And the way ">>" is treated when terminating nested template parameters.

Accepted in Java but not accepted in C++, I believe?

(Java also has to worry about ">>>" ;D)

Quote:

And the way variable initializations are sometimes treated as function declarations.

Eh? Got an example?

Carrus85
Quote:

And the way ">>" is treated when terminating nested template parameters.

This is fixed in C++0x, by the way.

Krzysztof Kluczek
Quote:

This is fixed in C++0x, by the way.

What's here to fix? C/C++ parser builds longest symbols it can build, which I find to be very consistent behavior, so ">>" will always be interpreted as bit shifting operator and not as two separate greater-than's. :)

Matt Weir

In the Allegro source code, I think it's in the gui stuff, you'll find an army of goto's. Suckers, you've been using them without knowing all this time, Mwa-ha-ha-ha-ha! ;D

Rampage
Quote:

What's here to fix? C/C++ parser builds longest symbols it can build, which I find to be very consistent behavior, so ">>" will always be interpreted as bit shifting operator and not as two separate greater-than's. :)

And templates within templates?

Krzysztof Kluczek
Quote:

And templates within templates?

Template arguments are specified using < an > operators, so its reasonable that < and >> operators shouldn't work here. I'm not sure how they are going to "fix" this in C++0x as this will overcomplicate either parser or syntax analyzer. In first case parser will have to know whether >> should be passed to syntax analyzer as >> operator or two >'s. In second case syntax analyzer will have to be aware of starting < which could have been many lines earlier. In C++ as it is now syntax analyzer has only to look one symbol forward, which makes writing C++ parser using bison/yacc quite straightforward. :)

Thomas Fjellstrom
Quote:

What's here to fix? C/C++ parser builds longest symbols it can build, which I find to be very consistent behavior, so ">>" will always be interpreted as bit shifting operator and not as two separate greater-than's. :)

Which is stupid. Theres context there to know what you've been parsing. You just saw a template started, why not realize that and see that its two separate >'s? Most parsers, especially generated ones, are too damn stupid to be of any real use. Just look at the horrible error messages they put out. They just don't have enough context to realize that the actual error is/was.

Quote:

this will overcomplicate either parser or syntax analyzer.

Hardly. GCC 4 has already replaced their DUMB bison/yacc parsers with hand rolled recursive decent parsers, which are already faster, but should allow error messages to improve (since you can place them at any point, instead of at places a generated parser finally notices an error), and allow the parser to know what its parsing. Its not that hard.

I have an oldish project that uses a lexicalanalyzer setup that allows you to push and pop modes for parsing, like for example, when parsing HTML, you can pop on a CSS analyzer, or javascript, all while the same parser pass is executing. Something like that, just done a little better would fix all the issues.

The only time complicating the parser/scanner in a compiler mattered was when you only had 2K ram :P Who bloody cares that theres a few extra KB of code in the compiler when it can properly parse, parses faster, and provides MUCH better error reports?

Krzysztof Kluczek
Quote:

Which is stupid. Theres context there to know what you've been parsing. You just saw a template started, why not realize that and see that its two separate >'s?

Then parse the code below. ;)

template<class _T> class foo;
template<int _I> class bar;

foo< bar< 1024 >> 2 >

Kitty Cat

2 isn't a valid symbol name, so you obviously meant
foo< bar< (1024 >> 2) >
and there's no harm in requiring the parenthesis, IMO. Also, you're missing a >. :P

orz
Quote:

What's here to fix? C/C++ parser builds longest symbols it can build, which I find to be very consistent behavior, so ">>" will always be interpreted as bit shifting operator and not as two separate greater-than's. :)

< and > are also used as matched pairs in template parameter lists. And, when multiple nested templates argument lists are terminated without anything intervening, the syntax gets rather weird. For an example with three levels of nesting, these are equivalent ways of naming the same type:

std::vector<std::pair<int,std::list<int > > >
std::vector<std::pair<int,std::list<int>>>>>>
std::vector<std::pair<int,std::list<int>>>>>

Quote:

And the way variable initializations are sometimes treated as function declarations.

Quote:

Eh? Got an example?

Hm... I thought this was covered in Myers Effective C++, but I can't find it right now.
Well, some quick experimentation turns up a case where things look a bit odd... this isn't much but it's the closest I can come up with atm:

class Foo {
public:
  int a;
  Foo ( ) : a(0) {}
};
int main(int argc, char **argv) {
  Foo bob();
  printf("%d\n", bob.a);//compile error; bob is a function, not an object
}

Bruce Perry
Quote:

For an example with three levels of nesting, these are equivalent ways of naming the same type:

That implies that someone decided ">>" should be accepted as a substitute for a single ">" in that context. Surely that's going to be even more confusing than just saying "Unexpected token '>>'"?

I can see what you mean about the functions and variables now. Wow, C++ is such a mess :-X Thanks for the example :)

Thomas Fjellstrom

Ok, I concede, C++ is so crappily designed that even a proper statefull parser couldn't easily handle it. ::)

Bob
orz said:

< and > are also used as matched pairs in template parameter lists. And, when multiple nested templates argument lists are terminated without anything intervening, the syntax gets rather weird. For an example with three levels of nesting, these are equivalent ways of naming the same type:
std::vector<std::pair<int,std::list<int > > >
std::vector<std::pair<int,std::list<int>>>>>>
std::vector<std::pair<int,std::list<int>>>>>

Umm...

#include <vector>
#include <list>
int main() {
  std::vector<std::pair<int,std::list<int > > > foo1;
  std::vector<std::pair<int,std::list<int>>>>>> foo2;
  std::vector<std::pair<int,std::list<int>>>>>  foo3;
}

MSVC 7.1:

$ cl temp.cpp -nologo
temp.cpp
temp.cpp(5) : error C2947: expecting '>' to terminate template-argument-list, found '>>'
temp.cpp(5) : error C2947: expecting '>' to terminate template-argument-list, found '>>'
temp.cpp(5) : error C2143: syntax error : missing ';' before '>'
temp.cpp(5) : error C2143: syntax error : missing ';' before '>'
temp.cpp(6) : error C2947: expecting '>' to terminate template-argument-list, found '>>'
temp.cpp(6) : error C2947: expecting '>' to terminate template-argument-list, found '>>'
temp.cpp(6) : error C2143: syntax error : missing ';' before '>'
temp.cpp(6) : error C2143: syntax error : missing ';' before '>'

MSVC 8.0:

$ cl -nologo temp.cpp
temp.cpp
temp.cpp(5) : error C2143: syntax error : missing ';' before '>'
temp.cpp(5) : error C2143: syntax error : missing ';' before '>'
temp.cpp(6) : error C2143: syntax error : missing ';' before '>'
temp.cpp(6) : error C2143: syntax error : missing ';' before '>'

GCC 3.4.4:

$ gcc temp.cpp
temp.cpp: In function `int main()':
temp.cpp:5: error: `>>' should be `> >' within a nested template argument list
temp.cpp:5: error: `foo2' undeclared (first use this function)
temp.cpp:5: error: (Each undeclared identifier is reported only once for each function it appears in.)
temp.cpp:5: error: spurious `>>', use `>' to terminate a template argument list
temp.cpp:5: error: expected primary-expression before '>>' token
temp.cpp:6: error: `>>' should be `> >' within a nested template argument list
temp.cpp:6: error: spurious `>>', use `>' to terminate a template argument list
temp.cpp:6: error: expected primary-expression before '>' token
temp.cpp:6: error: `foo3' undeclared (first use this function)

The C++ standard has no mention of this in the template grammar.

orz

Hm... perhaps that was MSVC6 only? Certainly I wouldn't actually choose that syntax, but I have seen it work.
edit: anyway, the most important point is that
std::vector<std::pair<int,std::list<int>>> foo1;
is not valid

HoHo
Quote:

Then parse the code below. ;)

Here you are :)

1#include <iostream>
2 
3template<class _T> class foo{
4 _T k;
5};
6template<int _I> class bar{
7 int i;
8 public:
9 bar(): i(_I){
10 std::cout<<i<<std::endl;
11 }
12 
13};
14 
15int main(){
16 foo< bar< 1024 >> 2 > > a;
17 return 0;
18}

compiled without any warnings and printed out 256 :)
gcc version 4.1.2 (Gentoo 4.1.2)

Krzysztof Kluczek
Quote:

Quote:
Then parse the code below. ;)

Here you are :)

Yes, I know that it should work OK. The question arises when we allow >> to be interpreted as two >'s closing two templates - the compiler comes to >> and isn't quite sure whether to treat it as two >'s or one >>. :)

Thomas Fjellstrom

Technically, if it has access to the symboltable as it parses, and has some extra lookahead, it can see its in foo and bar, and needs a int, which 1024 >> 2 resolves to. Its not impossible, and I bet at somepoint GCC could handle it with its new parser, unless they decide to stick strictly to the specs, which it never has before (gcc has the best extensions ;)).

Ron Ofir

Wow, lot's of interesting issues I never thought about, and probably never will... Anyway, what are trigraphs? And how would you label loops in Java? I don't recall ever seeing such a thing.

Kibiz0r
Quote:

Yes, I know that it should work OK. The question arises when we allow >> to be interpreted as two >'s closing two templates - the compiler comes to >> and isn't quite sure whether to treat it as two >'s or one >>. :)

Ick. If that's C++0x, I'm sticking to C++ && Boost.

Same neat features, none of the insanity.

Edit: Trigraphs.

BAF

C++ is over. C# by far is superior.

Thread #590604. Printed from Allegro.cc