We’ve traced the call and it’s coming from inside the house: A function call that always fails


A customer reported that they had a problem with a particular function added in Windows 7. The tricky bit was that the function was used only on very high-end hardware, not the sort of thing your average developer has lying around.

GROUP_AFFINITY GroupAffinity;
... code that initializes the GroupAffinity structure ...
if (!SetThreadGroupAffinity(hThread, &GrouAffinity, NULL));
{
 printf("SetThreadGroupAffinity failed: %d\n", GetLastError());
 return FALSE;
}

The customer reported that the function always failed with error 122 (ERROR_INSUFFICIENT_BUFFER) even though the buffer seems perfectly valid.

Since most of us don’t have machines with more than 64 processors, we couldn’t run the code on our own machines to see what happens. People asked some clarifying questions, like whether this code is compiled 32-bit or 64-bit (thinking that maybe there is an issue with the emulation layer), until somebody noticed that there was a stray semicolon at the end of the if statement.

The customer was naturally embarrassed, but was gracious enough to admit that, yup, removing the semicolon fixed the problem.

This reminds me of an incident many years ago. I was having a horrible time debugging a simple loop. It looked like the compiler was on drugs and was simply ignoring my loop conditions and always dropping out of the loop. At wit’s end, I asked a colleague to come to my office and serve as a second set of eyes. I talked him through the code as I single-stepped:

“Okay, so we set up the loop here…”

NODE pn = GetActiveNode();

“And we enter the loop, continuing while the node still needs processing.”

if (pn->NeedsProcessing())
{

“Okay, we entered the loop. Now we realign the skew rods on the node.”

 pn->RealignSkewRods();

“If the treadle is splayed, we need to calibrate the node against it.”

 if (IsSplayed()) pn->Recalibrate(this);

“And then we loop back to see if there is more work to be done on this node.”

}

“But look, even though the node needs processing «view node members», we don’t loop back. We just drop out of the loop. What’s going on?”

Um, that’s an if statement up there, not a while statement.

A moment of silence while I process this piece of information.

“All right then, sorry to bother you, hey, how about that sporting event last night, huh?”

Comments (64)
  1. Jim Lyon says:

    If I had a nickel for each time I've pointed out a problem like this in someone else's code, I'd be rich.

    Then again, if I had to pay nickel for each time I've bothered others to look at problems like this, I'd barely break even.

  2. JM says:

    I'll offer the requisite "this is the language's fault" angle, even though, of course, no language will ever make it the least bit hard to make silly mistakes, as Raymond's example points out.

    I don't recall which CS scientist it was who argued vigorously for having a "skip" statement in your language, but whoever it was, he'd be the first one to point out that you probably don't want to use the statement terminator to double as the skip statement.

    C could have decided to use { } as the only legal skip statement. But that probably would have complicated the scanner, or some such argument that seemed reasonable 30 years ago.

  3. Adam Rosenfield says:

    I once saw some code that was something like this:

    for(i = 0; i < N; i++) [lots and lots of spaces] ;

    {

     …

    }

    where there were enough spaces between the closing parenthesis and the semicolon that it scrolled off the screen in Visual Studio.  That was pretty devilish.  If I were to run into the same thing again, it'd be obvious to me now, since my editor of choice wraps long lines instead of adding scroll bars.

  4. ErikF says:

    That's the great thing about having someone to show code to: often they will see things that are in your 'blind spot'. I do that all the time when I'm writing stuff as well.

    Other scenarios where I find myself getting stuck are in stupidly-complicated nested statements. I think that compilers should issue warnings when you are hitting 6+ levels of nesting in a function (something like "Procedure too complex: consider refactoring!")

  5. Joe Fromm says:

    This sort of error is exactly why Python has significant white space – indentation defines program intent, rather than being a hint to the developer that is ignored by the compiler.  Many religious arguments have developed over that feature/misfeature, but situations like this are precisely what it is trying to solve.

  6. JM says:

    @ErikF: my compiler could go so far as to say "that function doesn't fit on a single screen, so I'm not compiling it". Variable screen sizes make this unenforceable in general, of course, but it really does save headaches.

    If I can't tell what it does by looking at one screenful of code for one minute, it's probably wrong. If it isn't, it's still apparently more complicated than I can comfortably understand, so it needs refactoring or documentation or it needs to be left alone (whatever's most appropriate).

    When looking at other people's code, it's too arrogant to say "I can't immediately understand this, so it's probably wrong", but it's too often true. If the other programmer can't readily explain it to you, you can consider it confirmed.

  7. Erin Lazzaro says:

    As an undergraduate I used to work at the university computer center helpdesk.  One time an experienced user (not at all like the freshmen I usually dealt with) came in with a Pascal program that just wouldn't compile.  He was extremely frustrated — he'd been banging his head on it for hours, but could not find anything wrong with the code.  I saw the problem immediately, but couldn't find a delicate enough way to say it:

    "You need to use the Pascal compiler for this.  The BASIC compiler just can't handle it."

    He didn't speak to me for the rest of the week.

  8. Eber I says:

    so that kind of stuff happens to Raymond too

  9. blah says:

    The real WTF is ignoring/suppressing compiler warnings.

  10. Kirill says:

    Don't Microsoft use any advanced static code analizers?

    [Yes, there are a lot of advanced static code analyzers nowadays. The really good ones requires a PhD to configure. Not sure what your point is. -Raymond]
  11. Evan says:

    @Kirill: Um, that's not MS's code.

  12. jdhardy says:

    Of course, in Python you can replace 'class' with 'def' and still have a syntactically correct program, and then spend the entire afternoon trying to figure out why you can't create an instance of the class…

  13. AsmGuru62 says:

    I agree with Paul M. Parks here.

    Disassembler is your friend in these cases.

  14. configurator says:

    That's why we have compiler warnings for this sort of thing.

    And rubber ducks.

  15. SimonRev says:

    Tend to agree with Blah.  Assuming the customer is using Visual Studio it will warn on code like that.  That should have been a pretty good clue that something was wrong.

    msdn.microsoft.com/…/8f1zx4y1%28VS.71%29.aspx

  16. I'm surprised that nobody noticed the typo in the reference to GroupAffinity yet ;-)

    [Y'know, just for the irony, I'm leaving it in! -Raymond]
  17. Jim Jones says:

    I got caught out with the Internet Explorer "trailing comma of death" when designing a website a couple of weeks ago.

    It took me two days to fix.

  18. Anonymous Coward says:

    In the case of an if statement there is never a need for a null statement, so why allow one at all?

    if(…); else; => Why is the test there at all?

    if(…) … else; => Why is the else there? (If it's because of another else and a parent if: use braces.)

    if(…); else …; => if(!…) …;

    Maybe macros could nuance this view, but in many places where a single ; is legal, it doesn't ever make any sense. And I think that in the few places where it might be useful, I think it should be a statement, e.g. "nop". I think the improved visibility would vastly

    outweigh the extra keystrokes.

    (Also, nitpick: GrouAffinity is not defined.)

  19. ErikF says:

    I agree that if we had a time machine, we should have persuaded DMR to have an explicit null statement. In fact, I seem to recall that "The C Programming Language" discussed that particular defect in its first edition! The good news is that most compilers have a warning that you can enable to search for these; the bad news is not all of them have it enabled by default.

  20. Lee says:

    @blah, @configurator: that's what I like about software houses where developers are encouraged to never check in code that has any warnings. Unfortunately, most of the places I've worked, I have to look for bugs in code that has hundreds of warnings, so I don't look at any of them until I'm desperate.

  21. CGomez says:

    "All right then, sorry to bother you, hey, how about that sporting event last night, huh?"

    Classic ending.

  22. MikeCaron says:

    if(someTestWithSideEffects()) {

       //TODO: implement logic for when this returns true

    }

    "What do you mean, empty block!? It's not empty at all!"

    Alternately, you mighty have this:

    //TODO: implement logic for when this returns true

    if(someTestWithSideEffects()) {

    }

  23. JM says:

    @Evan: obviously screens get bigger all the time while programmer capacities don't, so if you take my comment literally it makes no sense anyway. Besides, that you can always find exceptions to any coding guideline almost goes without saying. My point is just that stopping to think if maybe your function is too long is never a waste of time. Going the opposite extreme is no good either (I don't know if I prefer 1,000 three-line functions to one 3,000 line function, but whichever I encounter my day is probably ruined) but one screenful seems to work well as a rule of thumb in most cases.

  24. RichardDeeming says:

    I'm amazed that, despite several people mentioning Python in the comments, nobody's picked up the obvious reference: "One on't cross beams gone owt askew on treadle." :o)

  25. Nick says:

    [Y'know, just for the irony, I'm leaving it in! -Raymond]

    But Raymond, now when someone copy/pastes your best practices code example it won't compile for them!

  26. Ian T. Johns says:

    This reminds me of some devilish C tricks to screw with your team/friends/enemies:

    #define  while(x)  if(x)

    #define  if(x)     if(((x) != 0) ^ ((LINE % SOME_VAL == 0))

    The while() redefinition might not be immedaitely obvious but the if() definition would seem to randomly "optimize" out certain if statements (but only from certain lines) and would always evaluate the if conditional as FALSE. This problem would NOT be immediately obvious to the developer OR the compiler tech support.

  27. Ian T. Johns says:

    Above discussed on blog.regehr.org/…/574

  28. Evan says:

    It amazes me that the most common languages in use today will still admit that first example as valid code. As a PL researcher (okay it's really more like automatic program analysis techniques), it is also very discouraging. I don't think Python has it right — I find editing it too annoying because of the lack of ending delimiters — but C certainly doesn't either. I'd prefer some hybrid, where you need C-style delimiters but the indentation *must* match or it's a syntax error.

    I'm not saying you never need to write something like that… but which is better: having the language require that empty bodies be specified as {} (or perhaps even all bodies, but that's another issue) and in the very rare instance when that's useful, it gives you a compiler error and you put {}, or having the compiler silently do the "wrong" thing and then you spend hours of programmer time debugging it?

    @JM: "my compiler could go so far as to say "that function doesn't fit on a single screen, so I'm not compiling it". Variable screen sizes make this unenforceable in general, of course, but it really does save headaches."

    IMO there are too many times where long lines are really invaluable. I have had a number of occurrences where I'm declaring what is basically a table in the form of nested arrays, and *by far* the most readable way of doing it is to use lines that go well off the screen.

    The other thing I'd worry about is what exactly what the limit is. I don't mind some coding standards that sets the limit at like 120 characters or 100 or something like that — but I loathe 80 character limits with a passion. In the wonderful wide world of C++ templates it's not terribly uncommon for the name of a type to take up a substantial portion of that.

  29. Evan says:

    Oh, by the way, it's probably worth pointing out that Python-style significant whitespace would not, in-and-of-itself, help with this particular example. The code is still indented correctly, so a more Python-like C compiler would still accept it.

    The significant differences are twofold. First, Python does not have such a thing as an empty statement; you need to explicitly say 'pass', which is a lot more obvious than just a stray semicolon. Compare the above vs

       if (!SetThreadGroupAffinity(hThread, &GrouAffinity, NULL)) pass;

       {

           printf("SetThreadGroupAffinity failed: %dn", GetLastError());

           return FALSE;

       }

    Still might have to look for a moment, but it's at least a lot *more* clear.

    The second is that Python has no need for an arbitrary block of statements. But this is not true of C. Allowing a block anywhere (not just in the branch of a conditional or in a loop) in C restricts the scope of any variables declared within (something that Python wouldn't do because of it's weird scoping rules) and in C++ will constrain when destructors run (which also doesn't really have a Python equivalent). So you "can't" get rid of allowing arbitrary blocks.

  30. Paul M. Parks says:

    Dropping into disassembly view has helped me find a few boneheaded mistakes like that. Since finally getting around to learning assembly a few years ago (I was *very* late to that party), I've wondered how in the world I was able to impersonate a professional C/C++ developer for nigh on 15 years. Assembly rarely lies. (Rarely…)

  31. Dave (PhD) says:

    Yes, there are a lot of advanced static code analyzers nowadays. The

    really good ones requires a PhD to configure. Not sure what your point

    is.

    Well I didn't find it that hard :-).

    (PREfast requires an awful lot of work, not necessarily a PhD, and unfortunately isn't really that powerful. My favorite tool is Coverity, but then you're paying an arm and a leg for it too).

  32. Dave says:

    #Richard Deeming:

    I'm amazed that, despite several people mentioning Python in the

    comments, nobody's picked up the obvious reference: "One on't cross

    beams gone owt askew on treadle." :o)

    Well, as you know, there's nowt wrong with owt what mitherin clutterbucks don't barley grummit!

    (Oooohhh… 'ee were grand!).

  33. Adam Rosenfield says:

    @Anonymous Coward: There are plenty of valid uses.  Two examples off the top off my head are when the entire loop logic is in the loop test (like the string copy "while(*src++ = *dst++);") and when busy-waiting on a volatile memory location.

  34. DRX says:

    猿も木から落ちる

    Even monkeys fall from trees.

  35. configurator says:

    @Lee: Even if you ignore the warning, when something goes wrong and the misbehaving line of code has a squiggly, that is a pretty good indication of what the problem is.

    Where I work, we're not always encouraged to not commit code with warning – it really depends on the project. We try our best, but in some languages (Java comes to mind) it's almost impossible, and in some projects we have existing warning-ridden code bases.

  36. Evan says:

    @Adam Rosenfield: The AC explicitly said there's never a need of an empty block in an *if* statement. It can make sense in a loop, though I still think it should be disallowed as-is. (You can say 'while(…) {}' or 'while(…) pass;'. Those extra couple key presses won't hurt, I promise.)

    (Of course that's ignoring that an expression like '*src++ = *dst++' is an affront to good programming taste to begin with; the fact that particular loop is so idiomatic is the only reason that it's not strangle-worthy.)

  37. voo says:

    Actually that's a pretty good argument against using some indent style that puts the bracket on the next line – with K&R/1TBS you'd notice it right away imo ;)

    But while indent style is arguable, there's really NO good reason to use "while(*src++ = *dst++);" instead of "while(*src++ = *dst++) continue;" (I prefer that compared to {} because it's less likely to be overlooked, but that'd be fine for me too). That's just asking for problems.

    @JM I'd prefer the 1.000 three-line functions. Why? First of all I don't have to look at all the code I'm not interested in and second if the naming is reasonable I get some nice additional information for free.

  38. voo says:

    @configurator Huh? What compiler warnings do you ignore in Java? The only thing I can think of is having an old code base without Generics that's compiled with a modern JDK – but then one should go through that and fix it anyhow.. should be rather mechanic assuming nobody made a mess out of the code.

    Really can't think why java would be especially hard to get warning free – I find it much easier than in other languages.

  39. Cheong says:

    @Evan: I'd think forcing writng empty loop with empty block will work.

    while (!someFunc()) {};

    And actually I'm enforcing this practice like 5+ years now.

  40. Hereafter says:

    These are something i did before,

    both cases

  41. TC says:

    Similar to quoted story: I remember 40+ years ago, a group of people standing around a FORTRAN listing. They were focussed on 6 lines of code, trying to isolate a bug. Eventually someone looked at the corresponding object code on the system disk. Huh? Line blah hadn't compiled! It was a very old listing. Eventually someone noticed the dirty fingerprint at the start of that line. Under that fingerprint was just visile: a "C" in column 1! (the FORTRAN comment designator)

  42. GWO says:

    You don't need a complex static analyzer : "gcc -Wall Wextra -Werror" will catch the mistake (and suggest a clearer alternative if its not a mistake)

  43. Anton says:

    while (!someFunc()) {}

    while(true){

     if(someFunc()) break;

    }

  44. dave says:

    re: I like C

    A loop with an exit from the middle of the controller range for no good reason?

    That would fail my code inspection. Rewrite with top or bottom loop condition [ while (C) do S; -or- do S; while (C); ]

    See any text on structured programming.

    Apart from that, one should write C using the idioms that are known to C programmers.

  45. I like C says:

    That would fail my code inspection

    I would argue that this criterion is wrong, really. If you can rewrite the loop to have the condition at the top or at the bottom without introducing more conditions or more variables, then it should be done, of course. But it is much better to break out off a loop or a function (especially in case of errors) than to make the code more complicated, or to introduce additional variables.

    I like to see who you would rewrite my loop.

  46. JamesNT says:

    Mr. Chen,

    Despite this heroic attempt at trying to look human ("Hey, I make the same mistakes you guys make!"), you are still my programming GOD.

    JamesNT

  47. Medinoc says:

    And the moral of the story is the same as before ( blogs.msdn.com/…/1514567.aspx ) : Have someone else proofread you.

    But for the same reason, we never think of it.

  48. grumpy says:

    Which is why it's good to remain humble about our code. I know, it's hard, we're all coding gods and produce *amazing* code all the time, but sometimes, y'know, small tpying erors may sneak in. Not mistakes or bugs as such, just… cruft. Maintaining humility is the best way to avoid foot-in-mouth disease. :-)

  49. I like C says:

    > there's really NO good reason to use "while(*src++ = *dst++);"

    > instead of "while(*src++ = *dst++) continue;"

    There is really NO good reason to use "while(*src++ = *dst++);" instead of

    for () {

     *dst = *src;

     if (*dst == '') break;

     src++;

     dst++;

    }

    So much clearer (and with the right semantic for "src" and "dst :)).

    [I'm aware that src and dst will not have the same values after the loop as by "while(*dst++ = *src++);", but this may be more useful for string concatenation.]

  50. voo says:

    @Evan Imo that's not just a "fix it for the sole purpose of silencing the warning". Having a completely heterogenous Collection is usually a code smell and at least bad design (and what more can you expect a compiler warning to do than warn of these things? Sure it may not get fixed, because it's old working code, but in new code there's no excuse to get such a warning)

    I don't see "the editor doesn't know where to jump" as much of a problem. If I want to get out of a block I press backspace once in Python. To do the same in C I press } once – same effort, but the Python results looks much clearer.

  51. mrk says:

    @Lee Even better, where policy requires Warnings as Errors setting

  52. Simon Buchan says:

    Funny, I've only very rarely written these bugs, and it never took me long to find them when I did. I have plenty of *other* stupid bugs, so it's not like I think I'm some super coder or anything.

    @I like C: That is *waaaay* to hard a line to take. In fact, that code is so non-idiomatic C that it's *harder* for me to understand.

    I'm a big fan of the way python solves this, though, and every DSL I've created since has used layout. It's just better in every way: it's shorter (more meaning per line), prettier (less stylistic variance), and easier (less ways to screw up), all of which drive down the bug rate. I just wish it *either* only accepted indented blocks on the next line *or* accepted any aligned multiline blocks by counting characters, like:

    if foo: bar

    ……..baz

  53. I like C says:

    @Simon Buchan: > that it's *harder* for me to understand

    Why? To understand (debug!) a construct like "while(*dst++ = *src++);" you always need to decompose the steps and their correct timing in your brain. Thats unnecessary hard, especially when the loop also do some other things or calls functions with side-effects somewhere.

  54. I like C says:

    In a discussion like this, there is always one link to mention: http://www.de.ioccc.org/years.html

    For example, from 1994, weisberg:

    main(){

    int x=3,n,m=2,*t,*a,*b=0;

    while(b?o:((*(t=b=(int*)malloc(o))=2),a=t+1,o))n=*b,n>=m?c:x%n?(int)b++:N);

    }

    ???

  55. I like C says:

    @Dave:

    > See any text on structured programming.

    > Apart from that, one should write C using the idioms that are known to C programmers.

    That both statements together in this context make no well-grounded argument to me. "idioms that are known to C programmers" are in many cases no good examples for structured programming. The classic example here "while(*dst++ = *src++);" is more on the "spaghetti code" side than on the structured programming side.

  56. AsmGuru62 says:

    @dave:

    Here is a loop for looking for a character in a string

    (yeah… I know of strchr(), but just to prove a point):

    char* s = "CRAZY STRING!!"; // <– looking for 'G'

    char* t = s;

    char c;

    int found = 0;

    while (((c = *t++) != 0) && !found)

    {

    if (c == 'G') ++found;

    }

    So, how many times the condition code will check 'found' variable?

    A loop (written by non-dogmatic coder) with a break in a middle is more performant in the cases like this.

  57. Bruce says:

    "Since most of us don't have machines with more than 64 processors, we couldn't run the code on our own machines to see what happens."

    I know this is tangential to the story, but fortunately you can tell Windows to create groups of less than 64 processors per group for testing: msdn.microsoft.com/…/ff542298%28v=vs.85%29.aspx

  58. Evan says:

    Oh wow this thread got long. And it's just the sort of thing I like to tal^H^H^Hcomplain about.

    @Lee: "@blah, @configurator: that's what I like about software houses where developers are encouraged to never check in code that has any warnings"

    I did an internship at a place that turns on pretty much every warning they can get their paws on (at least that won't fail in system headers) and then builds with -Werror. Even *I* think that they may be excessive, but I still approve heavily.

    @JM: "My point is just that stopping to think if maybe your function is too long is never a waste of time."

    Oh, I totally agree; I just don't think there's anything close to a practical way to enforce it with tooling. (Well, tooling can help, but I think the most it can do is alert reasonable people to go use the cluebat a bit.)

    @configurator: "and in some projects we have existing warning-ridden code bases."

    Ugh, this is the worst. I once spent about 3 days taking a project that compiled with I think close to 10,000 warnings on default GCC settings and got it down to 0. (Most were like one warning repeated a bajillion times, but still.) I was so happy… of course turning on -Wall is still, uh, "interesting."

    @voo: "The only thing I can think of is having an old code base without Generics that's compiled with a modern JDK"

    I'm working on some code now that does that, and it's places where I can't put specific types because it's code that really can use anything. (There may be some fancy way to genericize the whole thing but I don't know how.) I mean, I could go in and put List<Object> instead of List, but it seems barely worth it. That would be one of those "fix it for the sole purpose of silencing the warning" thing. It's pretty low on the priority list.

    @cheuong00: "I'd think forcing writng empty loop with empty block will work."

    Oh, it totally does. My point is just that it should be absolutely enforced by the compiler.

    @Simon Burchan: "I'm a big fan of the way python solves this, though, and every DSL I've created since has used layout. It's just better in every way"

    I love *reading* Python; I hate writing it. The lack of block delimiters means your editor has fewer clues of where to indent to, which means it often gets it wrong. I stand by what I said before: the ideal in this area is to take the C approach and use delimiters, but then require that the indentation match.

    I think I'll stay out of the 'while(*dst++ = *src++)' discussion.

  59. 640k says:

    @Raymond: [Yes, there are a lot of advanced static code analyzers nowadays. The really good ones requires a PhD to configure. Not sure what your point is. -Raymond]

    1. MS has employees with PhDs.

    2. Good != cumbersome.

    3. VS 2010 code analyzer is not cumbersome to use.

    4. If one of the smartest employees of ms thinks THEIR OWN static code analysis tools are to cumbersome to use. Who are supposed to use them?

    @Evan: @Kirill: Um, that's not MS's code.

    On the contrary, MS own 100% of the code for prefix, prefast & visual studio code analyzer. MS have the developers as employees. There's NO excuse.

    @voo: I love *reading* Python; I hate writing it.

    Who cares? Remember, code is read more often that it is written. Usually a magnitude more often. Optimize for readability!

    Furthermore, I think this blog software stinks.

    [I still don't see what your point is. The stray semicolon was in a customer's code. Or are you saying that Microsoft's support policy should be "Customers may not ask questions until they've run the VS 2010 code analyzer over all their code"? (The VS 2010 code analyzer is not the one that requires a PhD to configure.) -Raymond]
  60. Neil says:

    This reminds me of the old Fortran story:

    DO5I=1.10

    instead of

    DO5I=1,10

    The nearest I could come up with in C is

    while (f()); while (g());

    as compared to

    do while (f()); while (g());

  61. Marcel says:

    @I like C: The IOCCC example makes no sense at all without the Makefile, because that's where the rest of the code is hidden.

  62. I like C says:

    @Marcel: Ok. But my point was that C allows you to write very cruel code (like the body of the main function of this example), very few "compact" lines with incredible complex semantics. The IOCCC website is of course for entertainment, but it also highlights this weakness of C very well.

    Ideally, C should redefine all kind of assignments to be statements, not expressions. Also, it should introduce boolean expressions at least by a requirement, that expressions in conditions must evaluate to boolean, and logical operators (&& and friends) can only operate with booleans. This both would greatly reduce the possibility to write unreadable one-liners, and the use of empty bodies in loops.

    [You are more than welcome to write up your proposal and submit it to the C standardization committee for consideration. Not sure why you need to tell us about it, though. -Raymond]
  63. 640k says:

    Customers should make sure their code is in perfect condition if they expect a good answer. What if the code doesn't compile?

    But of course, anyway, the first thing customer support should do is to run code analysis themselves. This could be done automatically.

    My point was that a *good* program, code analyzer or not, should not require a PhD. If any program require a PhD to use, it's not a good program.

    [The super-fancy static code analysis tool is a research project, not a commercial product. -Raymond]
  64. Evan says:

    @voo: "Imo that's not just a "fix it for the sole purpose of silencing the warning"."

    Hmm, looking at it again I might be able to put generics in to get rid of it, and it might not be too bad. Will require fairly extensive changes to the code in question though.

    @voo: "I don't see "the editor doesn't know where to jump" as much of a problem. If I want to get out of a block I press backspace once in Python. To do the same in C I press } once – same effort, but the Python results looks much clearer."

    The problem I have is that in C, the editor 'gets it wrong' (i.e. doesn't know that I want to insert a }) only once. Then I press } and it's right thereafter. However, in Python, the editors I've used (mostly Emacs) sometimes gets it wrong multiple times per end-of-block. I'll go through and hit backspace and continue. But then I'll go back and say "this if statement needs another elif", or "let's put another function between these two existing ones", and it'll get it wrong again. And then again. It's not *terribly* frequent, but it does happen.

    Like I said, I like the idea of making the compiler sensitive to whitespace to prevent this class of problems, and I went into Python with a very open mind on that matter. So I really do feel like I'm not just complaining because things aren't like how I'm used to. YMMV, but I really do find it more obnoxious to edit. I also don't find the {}s in C-like languages obnoxious.

    (And of course there are other problems with the Python approach, such as some forum software destroying indentation and thus the meaning of a Python program.)

    P.S. I totally had to use Wireshark to capture this post after the forum software dropped it. Whee for good software.

Comments are closed.