• Crabs (unregistered)

    Antiquated code translator not perfect. News at 11.

  • Jnx (unregistered)

    You could probably dedicate a whole site to posting "wtfy" generated code. I think that looks quite alright compared to most generated code I've seen. (not supposed to be modified, mind you)

    Obviously the conversion had some capability to detect the simplest loops, and falls back on a mathematically safe version if it doesn't work. If he'd have used the generated C I suppose the first thing he would have done would have been simplification, after that he'd have something that's actually quite usable.

    It's not a wtf, it's generated code...

  • (cs)

    "WTf2c-ness" I like that !!

    "The real WTF is.." that Albert did not have the formula to calculate the earth's magnetic field at any point committed to memory!

  • bg (unregistered)

    You know, if he had only written a wrapper around that function, he would have saved at least 10 minutes of development time.

  • mattman206 (unregistered)

    The Real WTF(tm) is that he's using F*RTRAN. (Young man, you are not allowed to talk like that around here, now go wash your mouth out with soap!)

  • Dwayne (unregistered) in reply to mattman206
    mattman206:
    The Real WTF(tm) is that he's using F*RTRAN. (Young man, you are not allowed to talk like that around here, now go wash your mouth out with soap!)
    Laugh all you want, but FORTRAN is still used in a lot scientific computing. Partially for historical reasons and because of legacy code, and partially because it has very good support for specifying the behavior of numeric types. That's important when you have to crunch a lot of numbers and need to know how rounding errors, precision, etc. will factor in to the result.
  • (cs) in reply to mattman206
    mattman206:
    The Real WTF(tm) is that he's using F*RTRAN. (Young man, you are not allowed to talk like that around here, now go wash your mouth out with soap!)
    The mention in the story that he originally decided against using the FORTRAN code, and only used it over the FORTRAN code because the generated C code sucked completely passed you by, didn't it? If you search for code on the 'net, you're limited to what languages people have written that code in...

    As to the WTF itself... I think the code is a pretty decent way of coding a "iterate from A to B, stepping by C" loop, where A, B and C could all be expressions, any of them could change during the loop, and the loop must count based on what the expressions were at the loop's start. D3 here stores the increment, and D4 stores the number of times to loop. D1 and D2 were probably used earlier for a similar purpose.

    It'd be a WTF if someone actually wrote that for this case, and it's a partial WTF that f2c didn't have more cases than "all the terms are constants" and "some/all the terms are variable"... but as by Jnx said, it's not WTF-y at all for generated code.

  • (cs)

    mattman206,

    He wasn't using FORTRAN at all, it's just that the examples he found were FORTRAN and C made by runing the FORTRAN code through a converter.

    Quite understandably, he used the much more understandable FORTRAN code(Heck, I don't know fortran, but I do know enough programing to figure out what it's doing) to make his C++ version of it.

    If you're going to be translating something, it's generally better to go back to the original source. I mean, if you take a novel, translate it from English to French, then propose creating a new German translation, which would you pick?

  • Luke (unregistered)

    High performance Fortran's still delivers the fastest numerical code of any high level languages.

  • (cs) in reply to Firethorn
    Firethorn:
    I mean, if you take a novel, translate it from English to French, then propose creating a new German translation, which would you pick?
    Nice... Though, a better analogy would be if the novel was translated into Mandarin and you wanted a Cantonese version... but the original translation was done through Babelfish.
  • codemonkey (unregistered)
      for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3)
      {
      ...
      }
    

    I like the whole D4=(n+m+D3)/D3... m=0 and D3=1 anyone? therefore D4=n+1.

  • NeoMojo (unregistered) in reply to Phlip
    Phlip:
    Firethorn:
    I mean, if you take a novel, translate it from English to French, then propose creating a new German translation, which would you pick?
    Nice... Though, a better analogy would be if the novel was translated into Mandarin and you wanted a Cantonese version... but the original translation was done through Babelfish.

    Then I would, of course, use the german version.

  • gomer (unregistered) in reply to codemonkey
    codemonkey:
    for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) { ... }

    I like the whole D4=(n+m+D3)/D3... m=0 and D3=1 anyone? therefore D4=n+1.

    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

  • Chris (unregistered) in reply to codemonkey

    You might want to check your rules of arithmetic precedence there: (X + Y) / Y != X + Y / Y

  • (cs) in reply to Chris
    gomer:
    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?
    Check again where the semicolons are. Then consider whether the second iteration is relevant.
    Chris:
    You might want to check your rules of arithmetic precedence there: (X + Y) / Y != X + Y / Y
    (X + Y) / Y == X + Y / Y when Y == 1.
  • (cs)

    The real WTF is that Alex didn't post some of the wrost code from that app, like these lines:

    *(p+n+m*13) = ct**(p+n-1+m*13); dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13); goto S50;
  • codemonkey (unregistered) in reply to Chris
    Chris:
    You might want to check your rules of arithmetic precedence there: (X + Y) / Y != X + Y / Y

    Umm... what? I hope that's not in response to my quote, because as far as I can tell my arithmetic is correct.

    D4=(n+m+D3)/D3 => D4 = (n+0+1)/1 => D4 = n+1

  • Ian (unregistered) in reply to gomer
    gomer:
    codemonkey:
    for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) { ... }

    I like the whole D4=(n+m+D3)/D3... m=0 and D3=1 anyone? therefore D4=n+1.

    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

    Which doesn't matter. Remember that for-loops in C/C++ are really while loops in disguise.

    The for-loop is equivalent to:

    m = 0;
    D3 = 1;
    D4 = (n + m + D3) / D3;
    while (D4 > 0) {
      ...
      D4--;
      m += D3
    }
    

    So D4 is calculated once before the loop starts. As codemonkey noted, it simplifies to D4 = n + 1.

  • codemonkey (unregistered) in reply to gomer
    gomer:
    codemonkey:
    for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) { ... }

    I like the whole D4=(n+m+D3)/D3... m=0 and D3=1 anyone? therefore D4=n+1.

    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

    This was already stated above, but I wanted to comment myself. gnomer...I hope you seriously missed that first semicolon because otherwise we need a refresher on C++ syntax!

  • Paul (unregistered) in reply to gomer
    gomer:
    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

    D4 is still n+1...

    AFAICS D3 is the step size, and D4 is the number of steps that need to be done. Although, then, I'd have thought the formula would be (n - m + D3)/ D3 ('-m' not '+m') - if 'm' starts off higher, you'd expect less steps, not more.

  • QuestionC (unregistered) in reply to djork
    djork:
    The real WTF is that Alex didn't post some of the wrost code from that app, like these lines:
    *(p+n+m*13) = ct**(p+n-1+m*13); dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13); goto S50;

    Thank you. I thought the posted code seemed a little weak, it's clearly just a generic form of a loop with a step. What's the above supposed to represent in Fortran?

  • Paul (unregistered) in reply to Paul
    Paul:
    gomer:
    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

    D4 is still n+1...

    AFAICS D3 is the step size, and D4 is the number of steps that need to be done. Although, then, I'd have thought the formula would be (n - m + D3)/ D3 ('-m' not '+m') - if 'm' starts off higher, you'd expect less steps, not more.

    Looking at (what I think is) the full source () there's another line where it IS '-m'

    for (m=0,D1=1,D2=(n-m+D1)/D1; D2>0; D2--,m+=D1)

    This has pretty much the same Fortran source, so I can't imagine why the generator uses '-m' in one place and '+m' in the other.

    Not that it matters, because 'm' is 0, so '-m' = '+m' - but you'd expect code generation to use the same construct in both places - especially since '+m' seems incorrect.

  • Smartass (unregistered) in reply to QuestionC
    QuestionC:
    djork:
    The real WTF is that Alex didn't post some of the wrost code from that app, like these lines:
    *(p+n+m*13) = ct**(p+n-1+m*13); dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13); goto S50;

    Thank you. I thought the posted code seemed a little weak, it's clearly just a generic form of a loop with a step. What's the above supposed to represent in Fortran?

    Obviously, it's:

    P(N,M)=CTP(N-1,M) DP(N,M)=CTDP(N-1,M)-ST*P(N-1,M)

    part of the way you calculate unnormalized associated legendre polynomials and derivatives via recursion relations

  • dibbler (unregistered) in reply to gomer
    gomer:
    codemonkey:
    for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3) { ... }

    I like the whole D4=(n+m+D3)/D3... m=0 and D3=1 anyone? therefore D4=n+1.

    Congratulations!!! You made it through the first iteration! Want to try the next when m no longer is 0?

    WTF? That code is executed exactly once, before we enter the loop, so m will always be 0. It is just generated code that safely handles non-constant loop counts.

  • diaphanein (unregistered)

    My favorite WTF in this code is the use of static locals unnecessarily. Hope you're not planning on multithreading anytime soon...

  • LC (unregistered)

    Smartass wins todays award for technobabble.

  • James (unregistered)

    Favorite (related) quote: "A computer without FORTRAN is like a fish without a bicycle."

  • dkf (unregistered) in reply to diaphanein
    diaphanein:
    My favorite WTF in this code is the use of static locals unnecessarily. Hope you're not planning on multithreading anytime soon...
    That's the part that makes me cringe too, especially as it also goes a long way towards reducing the C compiler's ability to optimize the mess away.
  • Anon (unregistered)

    I think the point of the WTF isn't that the generated code is ugly and complicated, it's that the National Geophysical Data Center thought it was worth posting on the web at all. If they don't have a decently written C version, then don't post a crap one instead.

  • (cs) in reply to Luke
    Luke:
    High performance Fortran's still delivers the fastest numerical code of any high level languages.

    Maybe we want to use the low performance fortran

  • (cs) in reply to Anon
    Anon:
    I think the point of the WTF isn't that the generated code is ugly and complicated, it's that the National Geophysical Data Center thought it was worth posting on the web at all. If they don't have a decently written C version, then don't post a crap one instead.

    Since a lot of scientific stuff is still done in fortran, then they didn't do anything wrong.

  • ac (unregistered) in reply to dkf
    dkf:
    diaphanein:
    My favorite WTF in this code is the use of static locals unnecessarily. Hope you're not planning on multithreading anytime soon...
    That's the part that makes me cringe too, especially as it also goes a long way towards reducing the C compiler's ability to optimize the mess away.
    Well, locals ARE static in Fortran (at least the older standards, it's been a while) so the translator either has to work out which locals don't need to be static to preserve the semantics (i.e. spot which ones are always initialised) or it can go the quick and dirty route and make them all static. Guess what...
  • Kunisaki (unregistered)

    The real WTF is using VB.

  • sburnap (unregistered)

    Wow, this brings back memories. When I was in college, I worked as a tech assistant to a physics professor whose main area of expertise was the earth's magnetic field. One of my myriad tasks was to "update" a number of simple programs written in sixties era fortran to Fortran 77. This essentially meant changing it to use such modern features as "for loops" and "local variables".

    For all I know, some of that "before" code was mine.

    The most amusing bits of the job involved me trying to explain to someone who learned to code in the sixties and then stopped learning what the point of "procedural programming" was. (In fairness to him, he had more important stuff to think about.)

    captcha: ninjas!

  • Vlad (unregistered) in reply to Phlip

    Any decent compiler should figure out that D3 is a constant and optimize it away. The first rule of the generated code is that you don't look at the generated code. You might be surprised by the decent optimized code always look a bit WTFs. For example spaghetti code is very common optimization technique called 'common subexpression' elimination, saves both time and memory.

  • Anon (unregistered) in reply to pitchingchris
    pitchingchris:
    Anon:
    I think the point of the WTF isn't that the generated code is ugly and complicated, it's that the National Geophysical Data Center thought it was worth posting on the web at all. If they don't have a decently written C version, then don't post a crap one instead.

    Since a lot of scientific stuff is still done in fortran, then they didn't do anything wrong.

    I didn't say anything was wrong with Fortran. Please pay attention. The wtf wasn't posting the Fortran version, it was posting a bad C version. If they can't do a half way decent job of converting it to C, they should have only posted the Fortran version.

  • (cs) in reply to Anon
    Anon:
    pitchingchris:
    Anon:
    I think the point of the WTF isn't that the generated code is ugly and complicated, it's that the National Geophysical Data Center thought it was worth posting on the web at all. If they don't have a decently written C version, then don't post a crap one instead.

    Since a lot of scientific stuff is still done in fortran, then they didn't do anything wrong.

    I didn't say anything was wrong with Fortran. Please pay attention. The wtf wasn't posting the Fortran version, it was posting a bad C version. If they can't do a half way decent job of converting it to C, they should have only posted the Fortran version.

    Point Taken. You're right. They shouldn't have used a language generator in the first place. Even if they don't charge money for it, they are attempting to "sell" you something that they didn't really author. Maybe they all knew fortran, not C. I do agree with you now, the C code should have been left out. They should have either just provided just the fortran or just some peudocode.

  • Alan (unregistered)

    C and Fortran handle multi-dimensional arrays differently and the code for translating nested loops probably allows for array access in the general case. That's assuming that there wasn't a relevent access trimmed out of the example....

  • Marcel (unregistered) in reply to pitchingchris
    pitchingchris:
    Luke:
    High performance Fortran's still delivers the fastest numerical code of any high level languages.

    Maybe we want to use the low performance fortran

    heh, that's not something you hear very often. "Want to use (...) fortran.

    The only reason to actually prefer it is exactly as given here, because the rest of the code is allready fortran. And of course, people will keep using fortran, because people will keep using fortran.

    Captha: Darwin, doesn't work for code.

  • (cs)

    I have spent several days trying to refactor f2c-generated code into proper, nice C++ code. At one point, I was about to write a public webpage about it, after all you start to see patterns after a while, which could be worth publishing... if it would lead to something. In the end, I always dumped the mess and wrote better code from scratch. Or found a much better library in perfect, fast C++ in the boost vault. Moral of the story: I would discourage anybody to try refactoring f2c-generated code. It is possible, but it takes ages.

  • Andrew (unregistered) in reply to QuestionC
    QuestionC:
    djork:
    The real WTF is that Alex didn't post some of the wrost code from that app, like these lines:
    *(p+n+m*13) = ct**(p+n-1+m*13); dp[m][n] = ct*dp[m][n-1]-st**(p+n-1+m*13); goto S50;

    Thank you. I thought the posted code seemed a little weak, it's clearly just a generic form of a loop with a step. What's the above supposed to represent in Fortran?

    These are array references. Fortran standard arrays map to insane pointer arithmetic in C. There are two basic differences.

    1. Fortan arrays allow user-defined index ranges. C must use pointer arithmetic to change ranges.

    INTEGER A(10:20) int a[11]; /* 0..11 must add +10 offset */

    1. Fortran standard arrays are column major, not row major. Binary data is stored in a file as column 1, column 2,...

    Some Fortran-to-C converters assume the data file is still Fortran-style. This leads to weird multi-dimensional pointer arithmetic. The code sample below likely maps these arrays.

    REAL P(M,N) float p[(n-1), (m-1)]; /* the indexes were swapped! */

    (p+n+m13) = ct**(p+n-1+m*13);

  • Randy (unregistered)

    I once took a large library (JPL's CSPICE) that had been translated from FORTRAN to C and wrapped in it JNI so we could use it in Java programs.

    The real WTF was I used perl to generate it all.

    CAPTCHA: ewww. 'nuff said.

  • (cs)

    I don't understand why these are different:

    for (n=1; n<=maxord; n++) { for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3)

    How did the translator decide it knew how to handle the first loop specifically, but had to handle the second one generically?

  • James (unregistered)

    As much as I hate FORTRAN ... it's still used and useful in the world. My Father (64 years old) works for Boeing Commercial. Right now he's in the testing group for the Dreamliner (787) project.

    Their simulation software is in FORTRAN.

    I told him that if he was any kind of programmer that he would've re-written the hundreds of thousands of lines of code into something more modern.

  • (cs)

    What Crabs said.

    The REAL WTF is that today's WTFs are about as WTF-y as leaving the milk out on a hot day will make the milk sour.

  • CoyneT (unregistered) in reply to chrismcb
    chrismcb:
    I don't understand why these are different:

    for (n=1; n<=maxord; n++) { for (m=0,D3=1,D4=(n+m+D3)/D3; D4>0; D4--,m+=D3)

    How did the translator decide it knew how to handle the first loop specifically, but had to handle the second one generically?

    I'm guessing that one or the other of starting with 0 or ending with N caused the translator to flip to a more generalized looping construct that overcomes some difference between C and FORTRAN looping.

    I have been dredging around and I think there was something weird about FORTRAN loops that didn't end exactly on the terminal, such as looping from 2 to 10 by 3's (I just couldn't remember what that was).

    So I poked around and ran into this on the web (at U. of London):

    The number of times the statements will be executed can be calculated from:
      iterations = ( stop + step - start ) / step
    

    Look familiar? D3=step, D4=# iterations.

    Apparently whoever built the translator fell back to this (sort of).

    Of course, the sign is wrong for m (as noted by someone). Since that makes the generalized loop wrong for any value of m other than zero, I'm guessing the Real WTF is that the example has a typo.

  • BillyBob (unregistered)

    So I had written a simple for loop in C++ and you couldn't believe the machine code generated for it:

    1001 10011010 1110 10101010 1101 10101111

    Could you believe that? :p

    The WTF is that the code was even refactored. Should have been wrapped, unit tests written and if all the unit tests pass, then you can just forget about the code.

    Most likely result of this is developer time wasted and subtle bugs introduced.

  • Case (unregistered)

    Two things I find hilarious about this one:

    1. That there are people reading this site who looked at that code and apparently just threw their hands up and gave up on translating what 1 simple for-loop declaration actually does. (Okay, you're excused if you have never ever done C before, but come on... on to part 2)

    2. That after spending that little time to read what it does, you then spent that much time posting a comment to make fun of something you didn't understand.

    Remember... if you don't understand why or know what is funny, the funny thing is probably you.

  • ha (unregistered) in reply to BillyBob

    In order to write unit tests you need a device to measure magnetic field. That's why unit tests are useless in math's and physic's scientific programs.

  • /df (unregistered) in reply to CoyneT
    CoyneT:
    chrismcb:
    ... How did the translator decide it knew how to handle the first loop specifically, but had to handle the second one generically?

    I'm guessing that one or the other of starting with 0 or ending with N caused the translator to flip to a more generalized looping construct that overcomes some difference between C and FORTRAN looping. ...

    In the (FORTRAN 66) construct DO 70 I=M1,M2,M3 ... 70 CONTINUE

    the Mi must be INTEGER constants or variables, that when the loop is first entered are positive and also satisfy M1<=M3 (so the loop is always executed at least once). Inside the loop, modifying I or any of the Mi that are variables leads to undefined results.

    [Subsidiary FORTRAN 'undefined result' WTF:

     SUBROUTINE MUTATE(N)
     N=3
     RETURN
    

    After calling MUTATE(2) in some FORTRAN 66 implementations, you could later find that 2=3.]

    In the WTF example's inner loop, as CoyneT points out, D4 is the loop count, which is needed since M starts at 0; D3 may be intended to insulate the translation from code that attempts to assign to the step variable in the loop.

Leave a comment on “WTf2c”

Log In or post as a guest

Replying to comment #:

« Return to Article