Can you spot the bug?
torhu

Just spent twenty minutes debugging this function before I realized why it seems to always return zero >:(;D::)

int ServerData::maxClients() const
{
    const QString& s = server[ServerColumn::PLAYERS];
    int slash = s.indexOf('/');

    return (slash =! -1) ? s.midRef(slash + 1).toInt() : 0;
}

Edgar Reynaldo

(slash =! -1)

=! != !=

torhu

Yeah...

RPG Hacker

Nice one! ;D

I think we all had small mistakes like that already, that threw our whole application over. For example: I once accidentally did something like this

((a, b, c, d), e)

instead of this

((a, b, c, d, e))

which in that special instance still compiled fine (the comma at the end there was interpreted as the comma operator), but made everything behave in a completely different and unexpected way. It took me a good while to find that error. At that time, I didn't even know a comma operator exists.

bamccaig

I may well be 5 AM, but I didn't spot that. That's a bitch. :P It's times like this that you need a linter!

Niunio

That never happens in Pascal... 8-);D

Bruce Perry

I spotted it :)

The best example I can think of for myself is trying to write ~/.ssh and ending up with ~./ssh or something. I don't often trip up over syntax in languages I use often :)

RPG Hacker, how come you needed double brackets?

RPG Hacker

RPG Hacker, how come you needed double brackets?

This was a bad example, because I just didn't remember the exact situation back then, but basically I think that I had some kind of construct with a number of brackets and needed an ", argument" inside one of the brackets, but accidentally placed it outside that bracket because I got confused by all the brackets. It compiled fine, but behaved completely differently.

beoran

That's why in C it's better to write the integer literal first, like (-1 != slash), etc. This is sometimes called "Yoda conditions".

torhu

I don't think that would help, but it would prevent you from writing = instead of ==.

APPEND: Oh wait...

bamccaig

I feel like <literal> == <variable> just reads wrong. It's like maths written like <math>ax^2+bx+c = y</math>. I don't know. I imagine there are cultures and classes and groups where that's normal. I just find it weird. In particular, I have never ever been stung by this particular bug (that I can remember). It's the sort of problem that should be recognizable by a linter if you do regularly. I personally find I look sideways at the aforementioned pattern because it reads unnaturally. Arguably it's a good pattern because it can eliminate a source of bugs, but I think you need to rewire your brain to read it, and I don't think the investment pays off. I could be wrong. Thus far, I haven't found that I appreciate it. One or two colleagues has tried this once in a while, and I always found it less readable and never found it added value. At the same time, I didn't notice the bug in the OP so maybe I'm getting old. :-/ Or maybe I was just tired. Either way, meh.

Append:

Perhaps what we should really take away from this is that the language should impose a particular order on us... Or use separate, unrelated operators or functions for assignment and comparison rather than trying to rearrange the operands to catch errors. One option could be =/ from Lisp land. That won't compile if you swap the characters. Alternatively, instead of ! which a lot of whiners recently complain about, use an explicit not keyword instead. *shrug* It isn't really a problem for me... At 30. Maybe 40?

torhu

C could be improved but the cost would be in backwards compatibility, and that's an issue for the most important programming language in the world for the last 40 years or so. You could change the rules for what counts as a token in C to not include =!, I guess...

bamccaig

That would turn something like x=!y; into invalid code. While in principle it's OK, it's not exactly a consistent rule, and I wouldn't want that applied to all operators. It's best just to test your code... :) Just because it compiles doesn't mean it's correct... Ideally, you should be able to test a unit a time and verify that what you just wrote is correct... None of that 3 days coding and then commit and compile cycles.

Bruce Perry
bamccaig said:

One option could be =/ from Lisp land. That won't compile if you swap the characters.

Not even as divide and assign?

Bob

As it happens, this was in the news recently.

Static code analysis tools are awesome.

RPG Hacker

WOW, that seems quite useful and powerful!
This reminds me of clang's code analysis, which is also surprisingly powerul in some places. For example: at work, we just recently made our WIP title PS4 NEO-compatible. This required switching to a newer version of the PS4 SDK, which also came with a newer version of clang. When trying to compile our code with that new SDK, clang actually complained that some memory was allocated via new(), but freed via delete[], which would lead to a certain crash (this wasn't in our code, we merely inherited it). Admittedly, allocating and freeing happened within the same function, but that's still some powerful code analysis for you. I really love clang for this and am glad that a certain other console is apparently going to use it as well (can't say which one due to NDAs, but if it turns out true, then it will be a major step up from that company's previous history and great news for me).

Thread #616433. Printed from Allegro.cc