• LCrawford (unregistered)

    There's a little known function of StringConversion.ToLower("2") == "Frist"

  • Prime Mover (unregistered)

    Haven't we learned anything this week?

    
    #define ONE 1
    #define TWO ONE + ONE
    
    override public void VerifyConnectionDetails(bool queryRequired)
    
    
    
    {
        if (this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase) || this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase))
        {
            // Let some time pass to simulate PIDS behavior
            System.Threading.Thread.Sleep(100);
            IsConnected = false;
        }
        else
        {
            IsConnected = true;
        }
               
        IsConnected = true;
    }
    
  • (nodebb)

    Why are the two comparisons identical? And, are there locales in which digits are case-sensitive?

  • (nodebb)

    Well, the IsConnected property could possibly have a side-effect where setting it to false then true would have a different effect than setting it to true then true, but...

  • Andy Miller (unregistered)

    Is this part of Santa's list checking software?

    Anything ending in '2' is naughty.

    He always checks it twice.

  • Alistair (unregistered) in reply to sjw

    https://www.silentalphabet.com/2020/03/uppercase-and-lowercase-numbers.html

  • Raphael (unregistered)

    TRWTF is the unused queryRequired parameter.

  • DaveD (unregistered) in reply to Prime Mover

    Prime Mover, you missed something:

    #define ONE_HUNDRED 100 ... System.Threading.Thread.Sleep(ONE_HUNDRED);

  • Robin (unregistered)

    Since I contribute comments occasionally under this name (which happens to be my real one), I felt I should clarify that this story is nothing to do with me. I see plenty of strange code from my colleagues, and contribute more than my fair share of WTFs myself, but I've yet to see anything quite this weird...

  • Prime Mover (unregistered)

    Incidentally, I'm not even sure about this, looks a bit dangerous to me:

        if (this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase) || this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase))
    

    Safer to do this:

        if (this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase) && this.Name.EndsWith(TWO.toString(), StringComparison.OrdinalIgnoreCase))
    
  • akozakie (unregistered)

    Lowercase and uppercase digits could work as a fully functional and extremely unreadable notation for imaginary numbers.

    You could even parse upper and lower case separately, meaning that (substituting z and s for 2 and 5 to have working cases) zSZsS, SzZsS and SZSzs would all be equivalent to 525+25i...

    Let's do that.

  • A. Glez. B. (unregistered)

    0: false 1: true 2: CONNECTION_NOT_FOUND

    Is that it?

  • (nodebb)

    Side Effects. My cow-orkers might come up with such :poo: code, too, so I am able to guess the idea behind this crap: IsConnectedis not just a property, it wille execute a lot of more crappy (and crappier) code when it is set. So, in the end it will trigger a reconnection attempt somehow.

    And for checking twice the same value, well, there's multithreading...

  • Hanzito (unregistered)

    I'm with Bernie: I've had similar code in C#. There was a class member dbIsOpen (or something like that), which was tested, but at one point it was set to true. Turned out it was a setter that actually opened the db connection. Can't remember much of the project, but it was full of surprises.

  • Duston (unregistered)

    "And, are there locales in which digits are case-sensitive?" Maybe there are systems that use Roman numerals?

  • my name is missing (unregistered)

    The scariest thought is that someone hired whoever wrote this.

  • Brian Boorman (unregistered) in reply to Raphael
    TRWTF is the unused queryRequired parameter.

    That may have been elided for purposes of the article. Don't assume that everything you see on this site is the complete code chunk.

  • Jay (unregistered) in reply to supermagle

    but the condition is running the exact same test on the exact same object twice. It's not clear that the "name" property will change or that the compiler wouldn't simplify this down to run the test once and just compare the result with it's self (pardon my ignorance on compiler logic).

  • Naomi (unregistered) in reply to Jay

    I don't believe the C# compiler can do that (in general), because it can't (in general) prove that the setter doesn't have side-effects. If the property setter can't be overridden, then it might be able to, but I'd be a little bit surprised if it did.

  • (nodebb) in reply to Jay

    The compiler will not optimize it away because a property getter is a method call. However the JITter can in-line the getter method, if it's appropriate per its rules, and if the getter body is just accessing a field, it could then fold the expression. This is highly dependent on the version of the framework - these optimizations are actively worked on by the framework team all the time.

    Now, can this be affected by multi threading? I highly doubt it. Assuming the Name property just reads a field, the chance of that field being set between the two checks is next to zero. If anything, the JITter optimizing that expression would prevent an unexpected behavior, not create one.

    Unless there's a parallel thread which modifies that field continuously in a loop, this guaranteeing a "collision", which would be crazy. And crazy is this developer's motto, so everything is possible.

    Addendum 2021-12-01 10:26: PS. The check in question is calling EndsWith, and it's unlikely even the JITter can figure out that it's a deterministic method, or that it can unlike its logic, because of the complicated culture handling shenanigans of string operations. So in the end, I think it will not be optimized, and the parallel thread with the crazy loop (which I'm convinced exists) can throw a monkey wrench into the mix.

    Addendum 2021-12-01 10:27: Pps. Inline, not unlike.

  • R Samuel Klatchko (unregistered) in reply to Alistair

    If you look at the source code you'll see that oldstyle numbers are just a font/formatting issue and not different code points.

    But I would be curious if a case insensitive comparison would treat ٢ (ARABIC-INDIC DIGIT TWO - https://www.fileformat.info/info/unicode/char/0662/index.htm) and 2 (DIGIT TWO - https://www.fileformat.info/info/unicode/char/0032/index.htm) as equal?

  • Argle (unregistered)

    I'm maintaining some code that is laced with things like this. An explanation for "why" may be that we lost a preceding context. For example, at one time it might have been:

    if ( name.EndsWith("Q") || name.EndsWith("X") )

    Then needed case independence and got it. Then the ending became 2 or 4, then eventually just 2. At this point it's not really about stupid, but it's about lazy. This is roughly like eating and having crumbs fall on your shirt or lap. It happens. But only a lazy slob can't be bothered to wipe away the crumbs.

  • (nodebb) in reply to Mr. TA

    Assuming the Name property just reads a field, the chance of that field being set between the two checks is next to zero.

    The narrowest "narrow timing window" bug I ever saw had a window of opportunity that was just three machine instructions long. In practice, it took consistently about 20 minutes for it to happen, from the moment the machine booted to the moment the bug occurred.

  • (nodebb)
    Anything ending in '2' is naughty.

    In several countries, "naught" means zero, so anything ending in "2" is , ummm, zero-ish?

  • Jim Jam (unregistered)

    The mystery of OrdinalIgnoreCase is simple: static code analysis tools mark locale-dependent comparisons as a code smell. For the cases like this, it is easier to give up and add a useless specification of comparer to shut it up. There also are cases when ordinal comparison is used for performance purposes, but this is not the case, clearly.

  • Loren Pechtel (unregistered)

    Argle beat me to it. This originally wasn't "2" and "2".

  • The Shadow Knows (unregistered) in reply to Argle

    That's probably the cause of many WTF examples - the need changes so the code gets amended, sometimes it's easier to leave the original there with a minor change for when the need changes back. In this case it wouldn't be major to recreate it, but there's plenty of times where it's a good chunk that you don't want to rebuild from scratch.

  • PIDS (unregistered)

    I don't know what iiiiisss, but I wan't one.

  • Chris (unregistered)

    All I know is that on most modern systems, lower case '2' minus upper case '2' should equal 32. Perhaps we can extend that to mean any number comprising lower case digits is always greater than any number consisting of upper case digits.

  • a robot (unregistered) in reply to Alistair

    obligatory xkcd reference https://xkcd.com/2206/

  • iOwnYu (unregistered)

    Nah... they just changed the order of the code lines so they go from longest to shortest.. looks more professional... unfortunately, sometimes it has side effects.. not always, just... sometimes...

  • Officer Johnny Holzkopf (unregistered) in reply to Duston

    LaTeX has case-selectable roman numerals for displaying things like counters: \newcounter{frist} \setcounter{frist}{2}; and then you can see the uppercase 2 using \Roman{frist}, while \roman{frist} will get you the lowercase 2.

  • (nodebb)

    Short Circuit.

  • James (unregistered) in reply to The Shadow Knows

    That's why we have version control. So code can be removed, but restored later without rewriting from scratch.

Leave a comment on “Two Comparisons, Hold the Case”

Log In or post as a guest

Replying to comment #:

« Return to Article