• (cs) in reply to Random832
    Namely, SIGFPE. Which stands for (you guessed it) floating-point exception.

    Note that actually trying to catch the exception can be problematic.

  • emanon (unregistered)

    Where's the punchline? That Mr. Jay Smith has it in for this guy but completely fails to examplify it? The WTF here goes to Mr. Smith, not to the senior guy. What a laugh. :-D

  • IMSoP (unregistered) in reply to Don't get it
    Don't get it:
    If you absolutely had to write this in C it would be along bit of code, something like:

    if( IsNan( A ) || IsNan( B ) ) return 0xC0003; else { Diff = A - B; if( Diff < 0.0 ) return 0xC0002; else if( Diff > 0.0 ) return 0xC0001; else return 0xC0004;

    I sincerely hope you had that nicely formatted and it got mangled when you submitted it, and this isn't actually your coding style. Apart from the missing } - which I presume goes at the end, it took me some minutes to work out what that last else was supposed to fit onto.

    If you want to be concise, drop the else after return:

    if( IsNan( A ) || IsNan( B ) ) return 0xC0003;
    Diff = A - B;
    if( Diff < 0.0 ) return 0xC0002;
    if( Diff > 0.0 ) return 0xC0001;
    return 0xC0004;
    

    Otherwise, use that tab key, even if you're going to skimp on braces!

    if( IsNan( A ) || IsNan( B ) )
    	return 0xC0003;
    else
    {
    	Diff = A - B;
    	if( Diff < 0.0 )
    		return 0xC0002;
    	else if( Diff > 0.0 )
    		return 0xC0001;
    	else
    		return 0xC0004;
    }
    
  • Greg (unregistered) in reply to Duke of New York
    Duke of New York:
    Greg:
    Actually, although it depends on the compiler, usually

    !0 != 1

    Most often, !0 is defined as MAX_INT (or something similar), so for a 16 bit system:

    !0 == 0xFFFF

    Much better to use the compiler defined TRUE and FALSE, or define your own as #define FALSE 0, and #define TRUE !FALSE and let the compiler decide what ! means and do the same thing every time.

    No. Just no. Go read the C standard for the ! operator (and all of the relational operators), and sin no more.

    Ah, I forgot the "all compilers follow the (C) standard, and never have any bugs" camp. Please, please tell me you're not building medical devices or missiles that will make some error about !foe.

    Maybe you've just been lucky, or are still in school, but there are some fairly stupid bugs in compilers sometimes. Use the #define's, or make ones yourself that are bulletproof. Don't assume that it follows the standard or you may end up explaining to the family how it's not really your fault the person died, it was the compiler that didn't follow the standard...see? Here's the quote from the standard! See!

  • bene (unregistered) in reply to Archimidas
    Archimidas:
    antred:
    SatanClaus:
    STL sucks. It rightly should be called non-STL. You better test it well!

    Errr what?? Unless you use a totally broken compiler / STL implementation, STL (or SC++L as it's called now) is the way to go.

    I second that. Try and write something faster than the STL libraries - I'll stick with the highly optimised, better-than-anything-I-can-dream-of-writing, library code :)

    If you have the need for very specific data structures (ie lists or whatever) its not incredibly hard to make them faster than the STL ones. Just that the STL stuff is guaranteed to work and cost a lot less developer time and is generally rather well known among people that know c++, so it incurs no extra time for learning a system for maintenance or whatever.

    And unless its something that for some wierd reason has an absurd need for speed, then what little speed you will gain by writing it yourself will not be worth it. Maintainability first.

  • (cs)

    Fun with operators: !0 = 1 0! = 1 0 != 1 0 = !1

    I think that's all of them. (1! unfortunately is not zero.)

  • Greg (unregistered) in reply to Capt. Obvious
    Capt. Obvious:
    Iago:
    Greg:
    Most often, !0 is defined as MAX_INT
    You may be thinking of Microsoft Visual Basic, which does indeed define True as 0xFFFF, but is not in fact a C compiler.
    Indeed, the whole Variant_Bool uses 0xFFFF(FFFF) as true. Drove me nuts, as implict casts (even in visual studio) have messed this up.

    I believe OS2 also used that schema for TRUE.

    I thought it was evil when I first saw it, but then came to realize it's beauty. It lets you use bitwise operators intermingled with binary values, and have it be correct for that bit.

    That said, in all my projects, !0 = 1, and 1 = false;

    I've seen it defined all sorts of ways. The best bet (IMHO) is to set one token (I suggest FALSE, or false if you must) to a value, say 0, then define the other token in terms of the negated first token, ie, TRUE = !FALSE. Then you are working with tokens not values for true and false. When people steadfastly assume they are values is when people get bit. (bad pun, sorry)

  • (cs) in reply to Mike Dimmick

    Legalize controlled statements (for er, uh, medical purposes...)!

  • (cs) in reply to Mike Dimmick
    Mike Dimmick:
    Steve:
    confused:
    Maybe it's too early in the morning, but what's with the !strcmp part? It seems like it'd work the same way without the ! since if the strings are equal, strcmp returns 0 and !0 is still 0.
    !0 is 1
    !0 is non-zero. It is not necessarily 1. C says 0 is treated as false, but any other value is true. The compiler is allowed to generate or use any value it likes.

    C++ says non-zero coerces to true while zero coerces to false. Strictly, the type of the expression in a controlled statement (if, while, etc) is bool in C++, int in C. I can't remember if C++ standardizes the result of (int)true, or whether it's left implementation-defined.

    You may well find that your compiler does produce 1 in debug builds, but in optimized release builds, it may be some other value depending on the expression.

    Anyway, don't do any mathematical expressions relying on the value of truth. You will get some unexpected answers.

    Dammit, forgot to quote.

    Legalize controlled statements (for er, uh, medical purposes)!

  • (cs) in reply to CNinja
    CNinja:
    Anonymous:
    Inline ASM, the hacker's best friend and coder's worst nightmare. I wonder how many picoseconds he may have saved with his ASM solution?

    None, it runs slower.

    Remember it's returning enumerated values... which he then has to do an if/else if/else test on, which adds even -more- branches to the prediction unit of the processor. If you just do the if/else if/else tests where they are needed instead of calling this function, it's much faster.

    ASM isn't always faster.

    Yea, just because it's in a "fast" language doesn't mean it's actually fast.

    It's perfectly possible to write bad asm code that runs slower than "good" vb6 code.

  • Lumberjack (unregistered) in reply to Loris
    Loris:
    http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918

    Holy shiznit! I've never seen that many sandy vaginas since I went to Ibiza!

  • (cs) in reply to hatterson
    hatterson:
    CNinja:
    Anonymous:
    Inline ASM, the hacker's best friend and coder's worst nightmare. I wonder how many picoseconds he may have saved with his ASM solution?

    None, it runs slower.

    Remember it's returning enumerated values... which he then has to do an if/else if/else test on, which adds even -more- branches to the prediction unit of the processor. If you just do the if/else if/else tests where they are needed instead of calling this function, it's much faster.

    ASM isn't always faster.

    Yea, just because it's in a "fast" language doesn't mean it's actually fast.

    It's perfectly possible to write bad asm code that runs slower than "good" vb6 code.

    This is wisdom

    I have this terrible need to puree a Jicama root salad immediately. I can almost sense the VB6 Fear.

    Yes, yes ... You're absolutely right. I need to talk to my friend, Mr Natural, right now.

    Goddamnit, those lizards are exceptionally fast. I paid good money for that root. I need whiskey, and I need it now, and fuck the mojo wire.

    I can see the Man down there, just by Seal Point ... He's always reliable. When I need "good" vb6 code, I need "good" vb6 code. The Man is always reliable. Best damn vb6 code in town ... or, for that matter, anywhere else.

    Even here in a hellhole lash-up hotel at the western edge of the Civilised World, with the waves almost wiping out that goddamn Pit Chihauhua -- I told Juan he should've checked the dentistry first -- I can see this.

    "Good" vb6 code is the way to go.

    That, a quart of ether, some Ibogaine, a credit card with no limit, a very fast car, and the Fear.

    Loathing can wait until later.

  • Duke of New York (unregistered) in reply to Greg
    Greg:
    Ah, I forgot the "all compilers follow the (C) standard, and never have any bugs" camp.
    Name a compiler that behaves as you describe.
  • (cs) in reply to Greg
    Greg:
    Duke of New York:
    Greg:
    Actually, although it depends on the compiler, usually

    !0 != 1

    Most often, !0 is defined as MAX_INT (or something similar), so for a 16 bit system:

    !0 == 0xFFFF

    Much better to use the compiler defined TRUE and FALSE, or define your own as #define FALSE 0, and #define TRUE !FALSE and let the compiler decide what ! means and do the same thing every time.

    No. Just no. Go read the C standard for the ! operator (and all of the relational operators), and sin no more.

    Ah, I forgot the "all compilers follow the (C) standard, and never have any bugs" camp.

    You are talking out of your goatse. The bug is in your head, you don't know the difference between logical and bitwise NOT, and I defy you to find a single compiler out there that makes the same mistake as you have been doing. Let me just remind you what you said:
    Greg:
    Actually, although it depends on the compiler, usually

    !0 != 1

    Most often, !0 is defined as MAX_INT (or something similar), so for a 16 bit system:

    !0 == 0xFFFF

    "Usually" !0 does not equal 1. Not "sometimes". Not "when there's a bug". "Most often". Your own literal words, idiot. Face it: you screwed up and were thinking about bitwise NOT but talking about logical NOT. Don't try and weasel out of it, the whole thread is there for anyone to see.
    Greg:
    Please, please tell me you're not building medical devices or missiles that will make some error about !foe.

    Maybe you've just been lucky, or are still in school, but there are some fairly stupid bugs in compilers sometimes. Use the #define's, or make ones yourself that are bulletproof. Don't assume that it follows the standard or you may end up explaining to the family how it's not really your fault the person died, it was the compiler that didn't follow the standard...see? Here's the quote from the standard! See!

    You are the idiot fresh out of school with no experience. I have thirty years experience and I didn't for one minute think I could stop learning new stuff just because I finished school, and so I can tell you pretty damn confidently that the way you address possible bugs in compilers is NOT BY WRITING CARGO CULT CODE.

    You do it by regular processes of testing, certification and verification. Measurable, repeatable, controlled scientific testing. Not superstitious garbage. If your compiler is so faulty that it can't do basic integer maths operations, AND YOU THINK YOU CAN MAKE IT ALL OK BY A COUPLE OF DEFINES, it is YOUR software that is going to kill people. And if your best plan is guessing rather than testing, that goes double

    Capt. Mainwaring:
    You stupid boy!
  • (cs) in reply to CNinja
    CNinja:
    Funny thing is, that code wrongs several massive orders of magnitude slower than a simple if/else statement.

    I had to read this sentence a couple of times before getting it, but now it makes more sense each time i read it.

    Kudos for verbing wrong!

  • Anonymous Coward (unregistered)

    #define StringUtil_Compare(a,b) !strcmp(a,b)

  • Dag (unregistered) in reply to minini
    minini:
    *EXACTLY* like my boss. do we refer to him here? the last gem is that he disallowed us to use strcoll() and we shall wait for his implementation.

    How do these people get to boss around anyone, nevermind sensible people with brains?

    If most of your code isn't application specific code then you're not using the right technology. Unless what you're making is in fact development tools including a compiler, a language, and a library to support it, it is nothing short of insanity to waste time and resources to recreate basic infrastructure code. It sounds like an ego trip on his own behalf, at the expense of shareholders, coworkers, customers - basically everyone but himself!

    And spending the companys time, money, and human resources on an ego trip isn't what it means to be a professional.

  • igor (unregistered) in reply to campkev

    that's the point of this daily WTF! :)

  • Duke of New York (unregistered)

    For the record, I have been programming away from school long enough to

    (1) encounter two actual C compiler bugs (2) stop overengineering my code for platform bugs that exist only in my head (3) accept C as C, instead of trying to turn it into Pascal or Basic

    Hopefully Greg will also someday reach the same skill level. For today's WTF coder, I have no such hopes.

  • xian (unregistered) in reply to antred
    antred:
    SatanClaus:
    STL sucks. It rightly should be called non-STL. You better test it well!

    Errr what?? Unless you use a totally broken compiler / STL implementation, STL (or SC++L as it's called now) is the way to go.

    STL is a massively broken hunk of crap, its cross platform support is a complete joke

  • DribbleDropper (unregistered)

    StringUtil_Compare must be the dumbest name for that function imaginable, because it no longer compares the strings, it only tests if they're equal.

    "perusing through" is an interesting expression. My dictionary says: peruse |pəˌruz| verb [ trans. ] formal read thoroughly or carefully : the pursed lips of an auditor perusing an unsatisfactory set of accounts.

    • examine carefully or at length : Laura perused a Caravaggio. ... USAGE The verb peruse means ‘read thoroughly and carefully.’ It is sometimes mistakenly taken to mean ‘read through quickly, glance over,’ as in: later documents will be perused rather than analyzed thoroughly, a sentence that technically makes no sense.

    So not only was it used in the 'wrong' meaning, the use of the preposition is also questionable at best. the author certainly was thinking along the lines of "skimming through". It's interesting how language develops along the weirdest paths.

  • (cs) in reply to Greg
    Greg:
    Actually, although it depends on the compiler, usually

    !0 != 1

    Most often, !0 is defined as MAX_INT (or something similar), so for a 16 bit system:

    !0 == 0xFFFF

    Much better to use the compiler defined TRUE and FALSE, or define your own as #define FALSE 0, and #define TRUE !FALSE and let the compiler decide what ! means and do the same thing every time.

    Pictures or it didn't happen!

    No, seriously. Sure, I have encountered compilers with bugs, bugs that I had to program around. But I have never ever seen a C compiler with a bug as drastic as not returning 1 for !0, and where MAX_INT was defined as 0xFFFF too. Compilers with errors as bad as those don't survive for long. So, show me. I want evidence!

  • Maya Posch (unregistered)

    Well, I can understand not wanting to use Boost libraries. I have tried to use a few of them and turned away in absolute disgust. Even MFC is less user-hostile, especially when the Boost library in question uses more namespaces and who knows what else to carve things up for no apparent reason, forcing one to wear out the ':' key in no-time. Generic design and basic API are two terms most Boost libraries have never even considered apparently.

    Yes, I did end up writing my own cross-platform library for my own needs. Sue me :P

    As for using ASM where it isn't warranted, that's just bad practice. I also agree that using the STL is generally a good idea as it's easy to use, standard and easy to maintain. Premature and/or needless optimizations are still evil.

  • Ps (unregistered)

    This guy doesn't fit my criteria for 'Competent and experienced'. In my experience, he sounds like a rookie with a talent for mashing code together. I expect he got the above function off the web somewhere. At the end of the day, commercial code has to go to a customer and then be maintained. And if a business does not understand that, they are sure to run into trouble. I would say that the bosses of this company don't really understand the processes of their own business - that is why this guy is allowed to continue to operate in this way. If they did understand just what he was doing (and then took action), then he would probably end up leaving to write lots of other 'clever' functions at another organisation where he was 'appreciated'. They probably see him as someone who is a 'doer' through his previous hacking efforts in the past. Without knowing that what in fact he is is basically a delinquent slinging code at their customers. Of course, when it comes to why the software can't be maintained in acceptable time scales, or why it doesn't scale etc then this guy will start blaming others. I expect he will then walk out on his colleagues siting 'stress'. So often these people can be left alone by others in the organisation who have seen them for what they really are - ticking bombs waiting to take the business and others down with them.

  • DribbleDropper (unregistered)

    I haven't programmed FPU assembler since the DOS days, but doesn't the code of the comparison function have a serious bug, namely that it doesn't call fwait before the conditional jump?

    I'm equally amazed that this crack programmer apparently couldn't figure out how to pop a value off the stack without writing it to memory.

  • (cs) in reply to xian
    xian:
    antred:
    SatanClaus:
    STL sucks. It rightly should be called non-STL. You better test it well!

    Errr what?? Unless you use a totally broken compiler / STL implementation, STL (or SC++L as it's called now) is the way to go.

    STL is a massively broken hunk of crap, its cross platform support is a complete joke

    OK.

    Let's assume this isn't a troll.

    Pick a platform, plus compiler. I'll write the fucking test program for you.

  • Michael (unregistered) in reply to alegr
    alegr:
    Loris:
    http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918

    Sorry, I just had to post this link :)

    I can believe that "senior programmer" == Linus Torvalds here. He's full of it.

    Every time I hear people talking about how nice a person Linus is, I look at his behaviour on technical mailing lists and snicker. Nice in comparison to whom? Idi Amin?

  • Michael (unregistered) in reply to Duke of New York
    Duke of New York:
    For the record, I have been programming away from school long enough to

    (1) encounter two actual C compiler bugs

    Only two? Hell, I had over a dozen in my first year out of school.

  • Duke of New York (unregistered) in reply to Michael
    Michael:
    Only two? Hell, I had over a dozen in my first year out of school.
    Unless this happened right about the time C was being adopted, I doubt it. A programmer only a year out of school normally isn't competent to recognize a true compiler bug (although it doesn't stop them from thinking they can).
  • lokey (unregistered) in reply to Jones
    Jones:
    !0 = 1

    I thought that was !0==1

  • lokey (unregistered) in reply to trincanapera
    trincanapera:
    I used to work with a girl like that. She wrote every single thing she needed for any project. She would never read or write any documentation and her libraries had all kinds of quirks that made a nightmare to use them.

    Example: 2 different functions that happened to return strings, one of them demanded that the string was pre-allocated by the caller but the other allocated the string itself so we would have to delete it later. And this was random, no valid reason was ever given.

    She never delivered a project on time. Strangely the boss trusted her and always nominated her to lead all projects. And I can't see why, because she was so very NOT hot!

    Yeah, But the Not Hot ones work harder horizontally.

  • lokey (unregistered) in reply to Mike Dimmick
    Mike Dimmick:
    Steve:
    confused:
    Maybe it's too early in the morning, but what's with the !strcmp part? It seems like it'd work the same way without the ! since if the strings are equal, strcmp returns 0 and !0 is still 0.
    !0 is 1
    !0 is non-zero. It is not necessarily 1. C says 0 is treated as false, but any other value is true. The compiler is allowed to generate or use any value it likes.

    C++ says non-zero coerces to true while zero coerces to false. Strictly, the type of the expression in a controlled statement (if, while, etc) is bool in C++, int in C. I can't remember if C++ standardizes the result of (int)true, or whether it's left implementation-defined.

    You may well find that your compiler does produce 1 in debug builds, but in optimized release builds, it may be some other value depending on the expression.

    Anyway, don't do any mathematical expressions relying on the value of truth. You will get some unexpected answers.

    Now we're talking politics?

  • ludus (unregistered) in reply to Michael
    Michael:
    alegr:
    Loris:
    http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918

    Sorry, I just had to post this link :)

    I can believe that "senior programmer" == Linus Torvalds here. He's full of it.

    Every time I hear people talking about how nice a person Linus is, I look at his behaviour on technical mailing lists and snicker. Nice in comparison to whom? Idi Amin?

    He is a fairly nice guy. He also cares very greatly about programming and the functionality of code. I'd rather have someone tell me in rude ways that something I did was stupid than have them not care.

    Though, some open source mailing lists are pretty much just epeen wagging and pissing contests. >.<

  • uxor (unregistered) in reply to pink_fairy
    pink_fairy:
    TheRealFoo:
    The XML parser bit in the article I understand. There is a ton of XML parsers out there, many bad, and the acceptable ones force specific structures upon your code that may or may not fit.

    I have yet to see a XML parser that is clean, fully standard-compliant and does not require you to overturn your data structures or code logic.

    (Links welcome.)

    So, that is the one part where I can understand why somebody might do that.

    Well, the introduction of XML into the mix was obviously a gratuitous invite to Wars O'Flame -- sheesh, an XML parser written from the ground up in assembler that'll only "work" on a 64-bit machine in the EN-US locale, what a concept... but only slightly worse than one built to work in Phuket -- but since you ask, here's a link. At least it's C++ related. It's sorta relevant.

    "Libraries like STL?" I've never heard a bunch of headers called a library before ... except, obviously, by Stepanov.

    What next? Re-implement libc.so.6? It's obviously in dire need of re-implementation. How hard could it be to do so in self-modifying MML assembler so that it copes with calls to libc.so.5, libc.so.4, etc ... and then just add a back-end to the assembly language of choice?

    http://en.wikipedia.org/wiki/Standard_template_library Wonder why people call STL a library?

  • deusued (unregistered)

    the real wtf is why the original coder isn't using strncmp.

  • pb (unregistered) in reply to Ps

    You must be the one maintaining his code.

    So when will you be moving up the chain and start writing new code. Maybe when you are able to show that you can do it and meet deadlines?

  • pb (unregistered)

    The real WTF is the writer of this story. He thinks the two pieces of code are interchangeable (because the target of this missive has a history of rewriting code).

    Hello!! the function name and signatures are different so there is no way these two pieces of code are for the same use.

  • Watson (unregistered) in reply to Pim
    Pim:
    Greg:
    Actually, although it depends on the compiler, usually

    !0 != 1

    Most often, !0 is defined as MAX_INT (or something similar), so for a 16 bit system:

    !0 == 0xFFFF

    Much better to use the compiler defined TRUE and FALSE, or define your own as #define FALSE 0, and #define TRUE !FALSE and let the compiler decide what ! means and do the same thing every time.

    Pictures or it didn't happen!

    No, seriously. Sure, I have encountered compilers with bugs, bugs that I had to program around. But I have never ever seen a C compiler with a bug as drastic as not returning 1 for !0, and where MAX_INT was defined as 0xFFFF too. Compilers with errors as bad as those don't survive for long. So, show me. I want evidence!

    And if you're writing for medical or weapons systems (or anything else life-critical) WTF would you be be using such an obviously broken compiler?

  • acid (unregistered) in reply to Jay
    Jay:
    Mike Dimmick:
    Anyway, don't ... rely on the value of truth. You will get some unexpected answers.

    Wow, is he talking about software or is he trying to make a profound philosophical comment?

    There's a difference?

  • Greg (unregistered) in reply to Duke of New York

    Ok, that's just silly. Name a compiler that is still version 1.0 (not due standards changing). Can you name a compiler that has NEVER had a bug?

    For the others that might read this, a classic was a Motorola C compiler for one of their DSP's where the pre-processor didn't recognize the literal '0'. Ie,

    #define FALSE 0

    Failed with FALSE being undefined. The work around for that version of the compiler was:

    #define FALSE (1-1)

    Any experienced software engineers care to explain why the expression is in ()'s? Maybe the kids still in school can learn something.

  • Duke of New York (unregistered)

    Still trying to weasel out of what you said, and pretend that you said something else. Just give it up.

  • ysth (unregistered) in reply to Greg
    Greg:
    Ah, I forgot the "all compilers follow the (C) standard, and never have any bugs" camp. Please, please tell me you're not building medical devices or missiles that will make some error about !foe.

    Maybe you've just been lucky, or are still in school, but there are some fairly stupid bugs in compilers sometimes. Use the #define's, or make ones yourself that are bulletproof. Don't assume that it follows the standard or you may end up explaining to the family how it's not really your fault the person died, it was the compiler that didn't follow the standard...see? Here's the quote from the standard! See!

    Better yet, how about you go and write an assembler in assembler, and use it to bootstrap itself. Then you will be perfectly secure from evil compiler bugs forever.

  • (cs) in reply to Greg
    Greg:
    #define FALSE (1-1)

    Any experienced software engineers care to explain why the expression is in ()'s?

    You're trying to change the subject now. Oh well. But this does remind me of that well-known trick:

    #define six 1+5 #define nine 8+1 (...) printf("%d", six*nine);

    where the result is 42. Does that answer your question?

  • BinaryDad (unregistered) in reply to Greg
    Greg:
    Ok, that's just silly. Name a compiler that is still version 1.0 (not due standards changing). Can you name a compiler that has NEVER had a bug?

    For the others that might read this, a classic was a Motorola C compiler for one of their DSP's where the pre-processor didn't recognize the literal '0'.

    The real issue with the assembler code, isn't that there may be a "bug" in the compiler, but that directly comparing two doubles is just a big no-no.

    Anybody who writes mission critical real-time systems for aerospace or other industries that require number crunching would not do a direct comparison. And plus, if some sort of NaN or other code has crept into the calculation, that's the fault of the programmer and not the compiler.

    It's far better to do something like

    
    inline int CompareDouble(double lhs, double rhs, double epsilon = 0.1-e6)
    {
        double delta = lhs - rhs;
        if (fabs(delta) <= epsilon))
        {
          // Within epsilon value to be close enough to being equal
          return EQUAL;
        }
        else if (delta > 0)
        {
          // rhs is less than lhs
          return LESS;
        }
    
        // Should only get to here if rhs is greater than lhs
        return GREATER;
    }
    

    There's no need for error prone assembler, which is platform dependant. Your tool-chain would have to pretty fucking dire if it somehow messes up the above code.

  • AdT (unregistered) in reply to xian
    xian:
    STL is a massively broken hunk of crap, its cross platform support is a complete joke

    In your case, it's more likely PEBKAC.

  • (cs) in reply to ysth
    ysth:
    Greg:
    Ah, I forgot the "all compilers follow the (C) standard, and never have any bugs" camp. Please, please tell me you're not building medical devices or missiles that will make some error about !foe.

    Maybe you've just been lucky, or are still in school, but there are some fairly stupid bugs in compilers sometimes. Use the #define's, or make ones yourself that are bulletproof. Don't assume that it follows the standard or you may end up explaining to the family how it's not really your fault the person died, it was the compiler that didn't follow the standard...see? Here's the quote from the standard! See!

    Better yet, how about you go and write an assembler in assembler, and use it to bootstrap itself. Then you will be perfectly secure from evil compiler bugs forever.
    Get a wooden table and a chisel.

  • (cs) in reply to BinaryDad
    BinaryDad:
    The real issue with the assembler code, isn't that there may be a "bug" in the compiler, but that directly comparing two doubles is just a big no-no.

    Anybody who writes mission critical real-time systems for aerospace or other industries that require number crunching would not do a direct comparison. And plus, if some sort of NaN or other code has crept into the calculation, that's the fault of the programmer and not the compiler.

    It's far better to do something like

    
    inline int CompareDouble(double lhs, double rhs, double epsilon = 0.1-e6)
    {
        double delta = lhs - rhs;
        if (fabs(delta) <= epsilon))
        {
          // Within epsilon value to be close enough to being equal
          return EQUAL;
        }
        else if (delta > 0)
        {
          // rhs is less than lhs
          return LESS;
        }
    
        // Should only get to here if rhs is greater than lhs
        return GREATER;
    }
    

    There's no need for error prone assembler, which is platform dependant. Your tool-chain would have to pretty fucking dire if it somehow messes up the above code.

    While I agree 100% with your sentiment, I disagree with your code. Your code is doing an absolute difference comparison, which is not very safe when using doubles. Sure, it can work well with a certain range of doubles, but CompareDouble(1e-10, 1e-50) will return EQUAL, but CompareDouble(100000000.000001, 100000000.000003) will return LESS. Probably not what most people would expect from a generic function.

    A more generic way would be to do a relative difference compare and use a much tighter epsilon, such as 1e-10. It would more computationally expensive, but probably have fewer problems.

    BTW, why 0.1e-6 and not 1e-7? Just curious.

  • (cs) in reply to BinaryDad
    BinaryDad:

    It's far better to do something like

    
    inline int CompareDouble(double lhs, double rhs, double epsilon = 0.1-e6)
    {
        double delta = lhs - rhs;
        if (fabs(delta) <= epsilon))
        {
          // Within epsilon value to be close enough to being equal
          return EQUAL;
        }
        else if (delta > 0)
        {
          // rhs is less than lhs
          return LESS;
        }
    
        // Should only get to here if rhs is greater than lhs
        return GREATER;
    }
    
    I do write for embedded systems (safety-critical ones even) and I'm still amused that people think this is needed because a floating-point compare is inaccurate.

    Fundamentally it's not; the issue isn't with the comparison itself. The reason you do this isn't because the compare is broken, but because you know there is enough error in the numbers being compared that you want a deadband around them for purposes of comparison.

    What's really fun is getting into discussions about how big the deadband needs to be.

  • Sean (unregistered)

    The WTF I see is why the hell anyone wrote a damn wrapper function around strcmp() in the first place. You might as well write:

    int sum_less_than(int left, int right, int sum) { return left + right < sum; }

    It doesn't even simplify the code, because the function name isn't that clear, the function call will be longer than the resulting code, and the code itself is not even remotely confusing in the first place. :/

  • (cs) in reply to Greg
    Greg:
    Ok, that's just silly. Name a compiler that is still version 1.0 (not due standards changing). Can you name a compiler that has NEVER had a bug?

    For the others that might read this, a classic was a Motorola C compiler for one of their DSP's where the pre-processor didn't recognize the literal '0'. Ie,

    #define FALSE 0

    Failed with FALSE being undefined. The work around for that version of the compiler was:

    #define FALSE (1-1)

    Any experienced software engineers care to explain why the expression is in ()'s? Maybe the kids still in school can learn something.

    So let's get this straight... by "Most often, !0 is defined as MAX_INT" you meant "There once was a compiler that defined false as (1-1)"?? Odd way of phrasing that.

Leave a comment on “Code Ownership Gone Awry”

Log In or post as a guest

Replying to comment #:

« Return to Article