• red_neck (unregistered)

    Them bullet holes is for speed.

  • (cs) in reply to Why is DailyWTF more like DailyWTFWTF
    Why is DailyWTF more like DailyWTFWTF:
    Did you squeeze that in between posting pictures of cats on anonymous message boards frequented exclusively by 14 year old school kids? Yeah, right. Once you leave school you'll learn some real skills, hopefully.
    It is a logical fallacy(*) to attempt to infer my age from your own lack of a sense of humour. The two are not causally linked.

    (*) - non-sequitur, since you ask.

  • (cs) in reply to Sir Twist
    Sir Twist:
    No, "for(;;)" is used for endless looks because "while (1)" makes the MSVC compiler complain "warning C4127: conditional expression is constant."
    I can't test it myself, but what about "while(true)"? While takes a bool after all.
  • schad (unregistered) in reply to vinnybad
    vinnybad:
    I can see where goto can be useful...especially if the task is OS code...but long jump? where can a thing like this be useful?

    The guys who make these instructions are smart...not dumb...can anyone think of a case where it can help?

    One case (which hasn't been mentioned already) is when the program is an uncertain state. For example, if you declare a signal handler for SIGSEGV in Unix, you can't safely call any functions or use any nontrivial data structures which are defined elsewhere in the program from the handler. So if you want to define a friendly SIGSEGV handler, what you do is use setjmp/longjmp to access your "BSOD" from the SIGSEGV handler. Basically, what you are doing is restoring your program to a known state so you can safely do meaningful work.

    That's honestly the only time I would ever use them. In all other circumstances, I think I would find another solution, even if that other solution is slower, takes more time to write, etc. And if that other solution is using a language that has native support for exceptions, then that's fine with me.

  • Anonymous Cowherd (unregistered) in reply to Thief^
    Thief^:
    I can't test it myself, but what about "while(true)"? While takes a bool after all.
    This being C, there is no such thing as a bool or a true.
  • Seb (unregistered) in reply to Jimbo

    Grow down already you sad old man.

  • Fat Freddie (unregistered)

    I once worked on a project where goto was banned but setjmp / longjmp was fine (yes I checked with the project manager). This was on a project where the cost of failure could be very high (we were subjecting critical aircraft components to simulated usage - if we broke the component all components would have to be replaced when they got to the simulated age of the test piece and we were only just ahead of many in service components).

  • Anonymous Cowherd (unregistered) in reply to schad
    schad:
    For example, if you declare a signal handler for SIGSEGV in Unix, you can't safely call any functions or use any nontrivial data structures which are defined elsewhere in the program from the handler. So if you want to define a friendly SIGSEGV handler, what you do is use setjmp/longjmp to access your "BSOD" from the SIGSEGV handler. Basically, what you are doing is restoring your program to a known state so you can safely do meaningful work.
    According to POSIX, longjmp isn't guaranteed to be safe to call inside a signal handler.
  • Whatthe.. (unregistered) in reply to Why is DailyWTF more like DailyWTFWTF
    Why is DailyWTF more like DailyWTFWTF:
    Did you squeeze that in between posting pictures of cats on anonymous message boards frequented exclusively by 14 year old school kids? Yeah, right. Once you leave school you'll learn some real skills, hopefully.

    Instead of throwing random insults at people you don't know, could you try to give us some insight into the mindset of the Real Guru (tm) as you claim to be? Just a little beyond 'read teh man page u noob' would be a big relief to give us entry-level c# babies a glimpse of light in this dark, dark place. Looks like we have a big, fat, smelly troll in our midst..

  • (cs) in reply to fluffy777
    fluffy777:
    Oh, and TRWTF is to be still using that valuable antique from the prehistoric DOS era, getch(), in the 21st century. (Does it still overflow your application's stack by trying to read all the available console input events in one go when you've just cut and pasted a couple of hundred kB of text into the window?)

    Aren't you confusing this with gets()?

    Nope, I'm definitely not!
    fluffy777:
    I don't see the implied buffer overflow vulnerability in a function that reads a single character.
    Nor did I, in fact I was thoroughly gobsmacked when I discovered what was going on, but I stepped right through the CRT source for getch() and it was perfectly clear what was going on. The getch()-using application that I was pasting pages and pages of text into was a win32 port of netcat, and pasting more than a certain amount of text made it segfault. Running through it in the debugger, I was astonished to find that it was peeking /the entire/ input buffer, into an alloca'd buffer of I-forget-how-much-but-maybe-32-or-64-kB on the stack. If there were enough input events waiting, KABOOOM!

    This was IIRC built with MSVC6. It's probably been fixed in more recent versions.

    fluffy777:
    If I remember correctly, (and I'm too lazy to check) getch is (sometimes?) an unbuffered getchar(), useful for real-time probing of user input.
    Yep, absolutely. It's the only-slightly-less-prehistoric equivalent of GET, as in
    10 PRINT "PRESS ANY KEY TO CONTINUE.";
    20 GET A$: IF A$ = "" GOTO 20
    
    I just can't even see a program containing getch() without subconciously associating it with the style of late-70s/early-80s home computer programs!
  • (cs) in reply to Mcoder
    Mcoder:
    Now, about the WTF, and answering to Bob (238533). No optimizer can work well with goto statements. Most of optimizing theory simply stops being useful when you start using it.
    Nah, that's not correct. A goto is simply another edge between BBs in the CFG, after all; there are already plenty of those in loops and conditionals anyway. The way in which longjmp is different from a goto and therefore inhibits optimisation is that it creates an exceptional edge in the flow graph; an edge which only one end of it is known (outgoing at the longjmp site, incoming at the setjmp site), and the other end could be anywhere.
  • (cs) in reply to Fat Freddie
    Fat Freddie:
    I once worked on a project where goto was banned but setjmp / longjmp was fine (yes I checked with the project manager). This was on a project where the cost of failure could be very high (we were subjecting critical aircraft components to simulated usage - if we broke the component all components would have to be replaced when they got to the simulated age of the test piece and we were only just ahead of many in service components).
    That's actually really strange from a safety/reliability perspective. Goto is nice and clean and deterministic, but setjmp/longjmp has implementation-defined behaviour - the values of automatic variables in the receiving stack frame aren't guaranteed, IIRC. And goto can only jump to local targets, which is more maintainable. I don't get their reasoning. I would have it the other way round.
  • (cs) in reply to monkeyPushButton
    monkeyPushButton:
    If I had used long jump, maybe I could have been First!
    With longjmp, it's still not too late! I called setjmp before the first comment - here, have a pointer to my jmp_buf and off you go!
  • Paul W. Homer (unregistered)

    Setjmp and longjmp were often used to implement complex error handling in a similar fashion to try/catch blocks. For something complex. like an interpreter, it was a cleaner, more robust way to implement consistent error handling. Usually, the convention in C was to bury it under macros or function calls.

    Setjmp has to save the full "runtime" context (so it can return to it later), so it would always be way way more expensive then a loop or a simple goto. It's very strange that anyone using it would think this was somehow faster than just a simple loop (more work is always more time).

    Paul.

  • Capt. Oblivious (unregistered) in reply to DaveK
    DaveK:
    Fat Freddie:
    I once worked on a project where goto was banned but setjmp / longjmp was fine (yes I checked with the project manager). This was on a project where the cost of failure could be very high (we were subjecting critical aircraft components to simulated usage - if we broke the component all components would have to be replaced when they got to the simulated age of the test piece and we were only just ahead of many in service components).
    That's actually really strange from a safety/reliability perspective. Goto is nice and clean and deterministic, but setjmp/longjmp has implementation-defined behaviour - the values of automatic variables in the receiving stack frame aren't guaranteed, IIRC. And goto can only jump to local targets, which is more maintainable. I don't get their reasoning. I would have it the other way round.

    Obviously, they were using longjmp for exception handling, which is cumbersome (at best) with a local goto. If longjmp is restricted to this role, it is relatively safe. And they can avoid unsafe goto's and longjmps by banning non-exception handling uses.

  • neophiliac (unregistered)

    I increased the loop size by an order of magnitude and got 11 seconds for the longjmp and 6 seconds for the loop.

  • (cs)

    looks like giovanni is in for the high jump...

  • adiener (unregistered) in reply to Anonymous Cowherd
    Anonymous Cowherd:
    Thief^:
    I can't test it myself, but what about "while(true)"? While takes a bool after all.
    This being C, there is no such thing as a bool or a true.
    C99 defines bool, true, and false. See stdbool.h.

    Also, while is not a function, so it may be misleading to say it takes a bool. It evaluates the expression between its parentheses on each iteration and skips if the result of evaluation is false/0.

  • (cs) in reply to Capt. Oblivious
    Capt. Oblivious:
    DaveK:
    Fat Freddie:
    I once worked on a project where goto was banned but setjmp / longjmp was fine
    That's actually really strange from a safety/reliability perspective.
    Obviously, they were using longjmp for exception handling, which is cumbersome (at best) with a local goto.
    Ah, good point. I read too much into the OP and thought it was implying that setjmp/longjmp "was fine" meant in a free-for-all sort of way rather than in a well-disciplined structured way.
  • bd_ (unregistered) in reply to schad

    This actually isn't safe. For example, let's say your signal comes while your program's in the middle of malloc. Once you siglongjmp out, you've corrupted your heap AND left the heap locked - touch malloc or free again and you'll lock up.

    The safe way to handle signals in unix is to write to a pipe (using the write() system call, which is safe in a signal handler) that your main loop is looking at. Or on recent linuxes, use signalfd.

  • (cs) in reply to DaveK

    longjmp is a WTF. I really can't understand why people use it. If you need it, ur doin' it rong.

    Sir Twist:
    "for(;;)" is used for endless looks because "while (1)" makes the MSVC compiler complain "warning C4127: conditional expression is constant."
    DaveK:
    I was astonished to find that it was peeking /the entire/ input buffer, into an alloca'd buffer of I-forget-how-much-but-maybe-32-or-64-kB on the stack. If there were enough input events waiting, KABOOOM!

    This was IIRC built with MSVC6. It's probably been fixed in more recent versions.

    The solution to these problems and more is simple: stop using that poor excuse for a compiler.

  • Jumpman Jr. (unregistered)

    Funny, the other day I was just reading about setjmp/longjmp in The Standard C Library by P.J. Plauger:

    The C Standard legislates the kind of expressions that can contain setjmp as a subexpression. The idea is to preclude any expressions that might store intermediate results in dynamic storage that is unknown (and unknowable) to setjmp. Thus you can write forms such as: switch (setjmp(buf))....., if (2 < setjmp(buf)) ....., if (!setjmp(buf)) ....., and the expression statement setjmp(buf).

    You can write no forms more complex than these. Note that you cannot reliably assign the value of setjmp, as in n = setjmp(buf). The expression may well evaluate properly, but the C Standard doesn't require it.

    (emphasis added)
  • Tenth of an inch (unregistered) in reply to rohypnol
    rohypnol:
    Remember, each "for(;;){" statement you write will give you 10 hacker points but it will also decrease your penis size by a tenth of an inch, and if you're a girl, it will decrease your breast size to 95% of what you had just before starting to write "for(;;){".

    Interesting... Do you happen to know any C idiom that has the opposite effect?

  • (cs) in reply to Dirk Diggler
    Dirk Diggler:
    I've been using C since the mid 80's and I thought I was pretty good at it. Mostly mixed C and assembly in micro-controllers. If I ever knew about this command, I've forgotten about it. So guess I learned something today.

    I've never heard of these commands either. Maybe they're compiler-specific.

    Yes, I know I could look it up.

    GOTO has its place; if it didn't, it wouldn't be included as a machine-level instruction on every chip ever made. I would say that since 90% of all programmers are crap, it's left out because most people can't be trusted with it.

    Case in point is today's example.

  • a brit (unregistered) in reply to virgil
    virgil:
    Sure, a for loop is faster, but i'm amazed how many people fail to see that longjmp is so much more enterprisey...
    longjmp uses XML?!
  • private static synchronized String longSignature() (unregistered) in reply to WinGuy
    WinGuy:
    Why is DailyWTF more like DailyWTFWTF:
    At least the goober at the top, who lacked knowledge of longjmp bothered to benchmark it and LEARN something (he should've read the man page, it would've alleviated the need for a benchmark).

    What's a 'Man Page'? I can't find it on my Start menu.

    For fun, google for 'man page'. Be sure to search for images! Hint: To not get fired, maybe do that on someone else's computer...

  • (cs)

    excelllllent function this .. added benefit of being self documenting

  • Loren Pechtel (unregistered)

    Fools! You're using the wrong yardstick!

    Longjmp is indeed much faster--at getting to code he!!.

  • (cs) in reply to themagni
    themagni:
    Dirk Diggler:
    I've been using C since the mid 80's and I thought I was pretty good at it. Mostly mixed C and assembly in micro-controllers. If I ever knew about this command, I've forgotten about it. So guess I learned something today.

    I've never heard of these commands either. Maybe they're compiler-specific.

    They're not "commands", they're functions, and they are part of the standard C library and have been ever since K'n'R days.
  • Snarky (unregistered) in reply to WinGuy
    WinGuy:
    Why is DailyWTF more like DailyWTFWTF:
    At least the goober at the top, who lacked knowledge of longjmp bothered to benchmark it and LEARN something (he should've read the man page, it would've alleviated the need for a benchmark).

    What's a 'Man Page'? I can't find it on my Start menu.

    Check your wife's browser history.

  • (cs) in reply to Loren Pechtel
    Loren Pechtel:
    Fools! You're using the wrong yardstick!

    Longjmp is indeed much faster--at getting to code he!!.

    Tonight, we longjmp in hell!

  • anon (unregistered)
    GOTO has its place; if it didn't, it wouldn't be included as a machine-level instruction on every chip ever made.

    I wonder, is machine-level if...else, for and while etc included?

  • Thp (unregistered) in reply to Daniel
    Daniel:
    Except, of course, that a language construct, like try/catch, isn't subject to such abuse as a library soluction, as this WTF illustrates so well.

    Don't be so sure.

    public static void calculate(SalesInfo sales, int loopdepth) {
        try {
            if (loopdepth > SALES_COUNT) throw new Exception("end of loop");
            sales.addvaluetosubtotal(sales.getValue(i));
            calculate(sales, loopdepth + 1);
        } catch (Exception e) {
            if (loopdepth == 0) return;
            throw new Exception("end of loop");
        }
    }
    
  • (cs)

    I remember inheriting a project where the main menu did a longjmp() if it didn't recognize the menu choice. For added entertainment value, the setjmp() bookmark wasn't set until after the first successful main menu choice. So, if you happened to hit a bad choice on the first try...

  • (cs) in reply to Rick
    Rick:
    Almost all 'C' compilers turn off optimization for the entire function, and sometimes the entire file, when it encounters a setjmp or longjmp. This is likely to be the major cause of the performance delay.

    Wait, what?

    I'm not aware of a compiler doing this. It's not that it couldn't be that someone does this, but "almost all"? Could you name some current compilers which do this?

  • neba (unregistered)

    Oh my god. Geeks everywhere. They actually tested it.

  • clickey McClicker (unregistered) in reply to WinGuy
    WinGuy:
    Why is DailyWTF more like DailyWTFWTF:
    At least the goober at the top, who lacked knowledge of longjmp bothered to benchmark it and LEARN something (he should've read the man page, it would've alleviated the need for a benchmark).

    What's a 'Man Page'? I can't find it on my Start menu.

    You must be using a 'girly' or 'womanly' OS.

  • (cs) in reply to themagni
    themagni:
    GOTO has its place; if it didn't, it wouldn't be included as a machine-level instruction on every chip ever made. I would say that since 90% of all programmers are crap, it's left out because most people can't be trusted with it.

    I disagree. While there are a very small number of cases where goto could be useful, I always avoided it if it can be accomplished without it. One of the basics of software engineering was that if you structured your code properly, 99% of the time you wouldn't need goto.

  • Bobblehead Troll (unregistered) in reply to JW
    JW:
    Konrads:
    People who write assembly code or setjmp like in this example in C for speed purposes are disregarding 30 years of work in field of compiler optimization. The better You can describe what You want to compiler, the better it optimizes.
    I totally agree. Library code is often faster than "user-optimized code", because the compiler can apply optimizations at the level of CPU/platform-dependent calls.

    I so love the smell of cargo cult in the afternoon.

    What about those programmers who actually write compilers, or library code? Hardly any of the C standard libraries are platform-optimized in any way and few compilers use more than 20% of the instruction set of the processor anyway, excepting some simple RISC machines. There is only one C compiler I know that does any kind of instruction-level vectorizing. With all the rest, guess what, you have to write it in assembler.

    Really, it is rather amusing to read comments by people who have never written or even read any assembly code to complain how slow it is, as well as those quoting the holy words of Knuth and obviously skipping the first long word that is outside their own jargon and it just comes out as 'optimization is the root of all evil'.

    In this example, yes... and there are many cases where people look at what the compiler made from their code and went 'WTF'.

    Trust no one. Not even yourself.

  • SnarfQuest (unregistered)

    Besides being useful for exception code, setjmp/longjmp can also be used to emulate the gosub/return pair from basic.

    (from memory, so don't laugh at mistakes) Create an array of jmp_buf's, and for a gosub use 'if (setjmp(jmpary[gs++])) {goto sbr;}', mark the top of a subroutine with an appropriate label like 'sbr:;', and for the return use 'longjmp(jmpary[--gs]);'. Best if wrapped up as a set of macros.

    Can't you imagine the look of horror in a future maintainers eyes?

  • (cs) in reply to Tenth of an inch

    You could try spamming "for(;;){" until penis size overflows

  • (cs) in reply to Tenth of an inch
    Tenth of an inch:
    rohypnol:
    Remember, each "for(;;){" statement you write will give you 10 hacker points but it will also decrease your penis size by a tenth of an inch, and if you're a girl, it will decrease your breast size to 95% of what you had just before starting to write "for(;;){".

    Interesting... Do you happen to know any C idiom that has the opposite effect?

    You could try spamming "for(;;){" until penis size overflows
  • (cs) in reply to Mcoder

    The RWTF is writing a business application in C in 2005. There are plenty of higher-level languages that would be much cheaper & safer to develop in.

    Also, this global routine called calculate() is hopefully anonymized. Otherwise, that's a terrible name.

  • Fat Freddie (unregistered) in reply to DaveK
    DaveK:
    Capt. Oblivious:
    DaveK:
    Fat Freddie:
    I once worked on a project where goto was banned but setjmp / longjmp was fine
    That's actually really strange from a safety/reliability perspective.
    Obviously, they were using longjmp for exception handling, which is cumbersome (at best) with a local goto.
    Ah, good point. I read too much into the OP and thought it was implying that setjmp/longjmp "was fine" meant in a free-for-all sort of way rather than in a well-disciplined structured way.
    Actually, you read too much into the intelligence of the project manager :-) I questioned the banning of goto (in C I used to use it very occasionally if it made the code easier to read) and she was adamant it wasn't allowed. I then asked if I could use setjmp and explained it was in the standard library and she said it must be fine then and it was ok to use it - needless to say I didn't actually use it but it was a good way of getting a handle on the PMs technical competence and attitude.
  • jmucchiello (unregistered)

    Actually, where longjmp outperforms looping is when you are looping inside 5 or nested functions and need to dump back to the original stack frame fast. If you had a case where 5 functions down the stack, you needed to start the next loop in the base stack frame, longjmp would out perform

    return SOME_BREAK_DEFINE; .... 
    
    if (func() == SOME_BREAK_DEFINE) return SOME_BREAK_DEFINE;
    

    repeat 4 times in 4 more functions and if (func() == SOME_BREAK_DEFINE) continue;

    It would be faster because it would not have to break down 5 stack frames and perform 5 ifs. It would just modify the stack once and jump.

    Still, this is such a rare occurrence, some languages call them exceptions. :-)

  • Richard (unregistered) in reply to Shai
    Shai:
    Nobody has commented on the minor-WTF RETURN_NOTHING macro, so I thought I should fill the void.

    Well, nobody except for Jackalope about 13 minutes before your post... but that's okay. And yeah, its pretty stupid.

  • (cs)

    Four seconds really is a long time. My first year at Google, I recall a Friday meeting where a guy was given an award for decreasing the average latency of a simple search by like 1/10 of a second. They sent him to Hawaii for a week, paid in full.

    I recall thinking "0.1 seconds isn't all that much... why would they give an award for such a small decrease?" And then I thought about how many searches were done every second, and thought about the horsepower behind each one.

    Four seconds is an eternity in some contexts.

  • fanha (unregistered)

    A philosophical view:

    If a programmer optimizes a program for speed and nobody tests it, does it make it faster?

    All sorts of rules-of-thumb are great for hypothesizing, but at the end of the day, knowing all the general optimization tricks in the world does you absolutely no good if your first principle when optimizing is not the test your relative performance EVERY TIME or don't consider it "optimizing".

  • Alex (unregistered) in reply to dkf
    dfk: No. A 'goto' becomes just a branch, and is very fast on modern computers. The test would be part of an 'if'...

    Dude, there's a test at the top of every for loop. Thus, test and branch.

  • Bob (unregistered)

    I don't feel so bad about using goto to jump into the middle of a while() loop now.

Leave a comment on “Longjmp - FOR SPEED!!!”

Log In or post as a guest

Replying to comment #:

« Return to Article