Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
something likelike what
imo the main use case for goto is breaking through multiple layers of nested loops, for everything else there's better options
setupcode1()
if (somethinggowrong)
goto td1;
setupcode2()
if (somethinggowrong)
goto td2;
setupcode3()
if (somethinggowrong)
goto td3;
setupcode4()
if (somethinggowrong)
goto td4;
dostuff()
td4:
teardowncode4()
td3:
teardowncode3()
td2:
teardowncode2()
td1:
teardowncode1()
Yeah I did a tardery. Don't drink and post.My goodness, no. I cited the context of the paper: go to statements. This is Knuth firing back at Dijkstra's "Go To Considered Harmful", and is Knuth explaining that, no, GOTO commands are just fine, and shoehorning other control flow methods into the space where GOTO fits naturally is bad practice.
Some reading materials, because apparently people in this thread are illiterate.
https://archive.org/details/Structured_Programming__Dahl_Dijkstra_Hoare - Structured Programming by Dahl, Dijkstra, Hoare
https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf - go to Considered Harmful by Dijkstra
https://dl.acm.org/doi/epdf/10.1145/356635.356640 - Structured Programming with go to Statements by Knuth
If you think that mathematicians keep a standard for denoting first element you are mistaken. Infact it is even less standarized than in programing as most often it is whatever is most convinenthonestly i believe if arrays werent a syntax sugar over a pointer but their own object/abstraction they would start at one, since in mathematics first element of something is denoted using a "1" not "0"
but it does make math a little bit wonky, for example taking a mod of something would require adding a one and such
I think we read different papers. Because Knuth is stating quite clearly that goto should be the last resort for when higher level control flows do not suffice. And even then the first question should be whether you are thinking about problem in right manner.My goodness, no. I cited the context of the paper: go to statements. This is Knuth firing back at Dijkstra's "Go To Considered Harmful", and is Knuth explaining that, no, GOTO commands are just fine, and shoehorning other control flow methods into the space where GOTO fits naturally is bad practice.
Other than that recursion elimination is solved by tail call optimization nowadays.He taught them to use go t o
only in unusual special cases where i f and
w h i l e aren't right, b u t he found [78] t h a t
"A disturbingly large percentage of the
students ran into situations t h a t require
go to's, and sure enough, it was often because
w h i l e didn't work well to their plan, b u t
almost invariably because their plan was
poorly thought out." Because of arguments
like this, I ' d say we should, indeed, abolish
go t o from the high-level language, at least
as an experiment in training people to
formulate their abstractions more carefully.
This does have a beneficial effect on style,
although I would not make such a prohibi-
tion if the new language features described
above were not available. T h e question is
whether we should ban it, or educate against
i t ; should we a t t e m p t to legislate program
morality? In this case I vote for legislation,
with appropriate legal substitutes in place
of the former overwhelming temptations.
its great to see people were calling things "literally 1984" even before the internethttps://dl.acm.org/doi/epdf/10.1145/356635.356640 - Structured Programming with go to Statements by Knuth
thats how APL niggers actually genuinely unironically write c btwWhy even bother with array indices? Any decent language worth using has support for foreach.
C:#include <stdio.h> #define foreach(e,a)for(__typeof__(*a)*e=a,*a##_last=(a+(sizeof(a)/sizeof(*a))-1);e<=a##_last;++e) int main(void) { int xs[]={1,2,3,4,5}; foreach(x,xs)*x=*x%2?*x*3+1:*x/2; foreach(x,xs)printf("%d%s",*x,x!=xs_last?", ":"\n"); }
This might look hideous, but this is next level memory management which saves multiple bytes of disk space by removing extranous whitespace and using minimal variable names. But I guess this sort of thing would probably go over the heads of a bunch of cave-dwelling webdevs who only know JavaScript...![]()
something like
Code:setupcode1() if (somethinggowrong) goto td1; setupcode2() if (somethinggowrong) goto td2; setupcode3() if (somethinggowrong) goto td3; setupcode4() if (somethinggowrong) goto td4; dostuff() td4: teardowncode4() td3: teardowncode3() td2: teardowncode2() td1: teardowncode1()
Can be useful for handling cleanup code.
yeahthis feels like the type of thing that raii was made to avoid
gcc manual said:cleanup (cleanup_function)
This attribute applies to variables.
The cleanup attribute runs a function when the variable goesout of scope. This attribute can only be applied to auto functionscope variables; it may not be applied to parameters or variables with static storage duration. The function must take one parameter,a pointer to a type compatible with the variable. The return value of the function (if any) is ignored.
When multiple variables in the same scope have cleanupattributes, at exit from the scope their associated cleanup functionsare run in reverse order of definition (last defined, first cleanup).
Yeah, in most languages these days it isn't relevant. But in something like pure c, it does often make sense.this feels like the type of thing that raii was made to avoid
You're taking my comments out of context. Here is how the Conclusion begins.I think we read different papers. Because Knuth is stating quite clearly that goto should be the last resort for when higher level control flows do not suffice. And even then the first question should be whether you are thinking about problem in right manner.
I think it's perfectly acceptable interpretation given modern context, especially given that he himself states that "new types of syntaxes are being developed"."should be the last resort" is stretching what Knuth is saying here.
I don't think I would interpret what Knuth is saying as this. I honestly believe he has opposite intention from this text, especially if you read later part of his conclusion which talks about students.My statement "GOTO commands are just fine" shouldn't be read as "GOTO commands are always fine", but more that "GOTO elimination" as a dogmatic belief is an instance of premature optimization.
C conditional teardown/error handling.Are there any real world cases for go to other than continuing from a deeply nested loop? I can't think of any in my experience, and this was a specific circumstance, usually nested loops are a code smell.
Well, all things considered, all programming is an abstraction over selection, sequence, and repetition, unconditional GOTO being sequence and conditional GOTO being selection/repetition; or rather, all you need is BEQ/JE/conditional jump and you're good to go; the unconditional jump is already a single layer of abstraction over the conditional jump where the operands are always true/equal.But goto is almost the only control statement. Everything else is just syntactic sugar on top of goto.
If is just conditional goto. Function calls are push stuff on the stack then goto. Return is pop stuff off the stack and goto.
foo = input()
while not len(foo) == 0:
#... do something ...
foo = input()
loop_start:
foo = input();
if (len(foo) == 0) goto loop_end;
/* ... do something ... */
goto loop_start
loop_end:
while(1)
{
foo = input();
if (len(foo) == 0) break;
/* ... do something ...*/
}
/* Try to acquire using method 1 */
if (!succeeded)
{
/* Try to acquire using method 2 */
if (!succeeded)
{
/* Try to acquire using method 3, and so on... */
}
}
/* Complex usage of thing */
/* Try to acquire using method 1 */
if (!succeeded)
{
/* Try to acquire using method 2 */
}
if (!succeeded)
{
/* Try to acquire using method 3, and so on... */
}
/* ... */
/* Complex use of thing acquired */
/* Attempt to acquire using method 1 */
if (succeeded) goto use;
/* Attempt to acquire using method 2 */
if (succeeded) goto use;
/* Attempt to acquire using method 3, and so on */
if (succeeded) goto use;
/* ... */
use:
/* Complex use of acquired thing */
I really don't like RAII in C++ because it hides acquisition of scarce resources by making them look like normal variable declarations. SinceThat's simplifcation that's probably a reason why RAII have such a bad rep. RAII is not about memory, it's about resources which are much more abstract.
Containers still uses RAII to construct/destruct objects, but you don't have to allocate memory a lot of the times.
Moreover you can easily compose classes which should uphold their invariants thanks to ctors and release everything thanks to dtors after just object of top class is destroyed. All without having to manually keep track of what's need to be initialized and what's need to freed.
RAII is absolutely killer feature of C++, and reason why it keeps dominating in certain industries.
using can't currently be followed by a left parenthesis in legal C++ code, I suggest that a new statement of the form using (decl1; decl2; ...) statement be introduced, where all the declarations have types that have been declared with a new [[resource]] attribute or are locally declared as having a new [[large]] attribute. This way, it would be clear that there's more going on that a usual local variable.class Lock {
Lock(Mutex *m) { ... } // acquire mutex
~Lock() { ... } // release mutex
}
...
if (...) {
Lock lock(some_mutex);
...
} else {
std::vector<T> vec(N); // allocate ~5% of total system memory
...
}
class [[resource]] Lock { // now legal in using (...) statements and a warning when used elsewhere
....
}
...
if (...) {
using (Lock lock(some_mutex)) {
...
}
} else {
using ([[large]] std::vector<T> vec(N)) {
....
}
}
Agreed, but only if they adopt full Icon semantics for arrays, where the indices refer to the gaps between elements, identify the element to their immediate right, and run in both directions: so a[1] is the first element of a, a[-1] is the last element of a, and a[2:0] is a slice of a containing everything but the first element (i.e., everything from the position between the first and second elements and the position immediately following the end of the array)....
guys i think arrays SHOULD start at 1
] = 7;
Of course, the truly skilled at coping with an insistence on avoiding gotos will factor out all the "acquire" parts into a separate procedure so that they can use "return" to skip over all the remaining methods on success. [...] Basically, when things get complex, programmers often reach for "return" or "break" or "continue", not because they want to return a value or explicitly need a conditional loop, but because they need "goto" but have been told "goto" is bad (or, worse, their language doesn't have it).
goto? Where? Why? return, break, and continue, are not just synonyms for goto, they have extra semantic meaning. I don't have to look for the label or assume the programmers intention. Goto has a bad image because most of the people definding it are midwits. RAII (and defer) are much better solutions to the only problem that goto actually solves.def get_next_line():
# add linux support (^D)
try:
line = input()
except EOFError:
return None
# empty string is falsey, but maybe you want it to be explicit?
if len(line) == 0:
return False
return line
while line := get_next_line():
print(line)
C can do that, as long as you use single characters. I was having trouble with emojis, I hope the cursed array access makes up for it.i think arrays should take indices that are unicode strings
arr[] = 60;
arr[] = 7;
int i = [arr[] + arr[
];![]()
cout << i; //67
chars are just ints, which are (de facto) signed 32 bit, big enough for any unicode character but you might have trouble with negative indices, depending on the emoji.#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *x = malloc('€');
x['['] = 34,
x[']'] = 35;
printf("%u\n", '['[x] + ']'[x]);
}