Programmer time and the pitfalls of wasteful work

Programmer time is precious. This realization should shape our approach to software development, focusing our efforts on tasks that genuinely contribute to the improvement of our code and the software ecosystem.

 

What does matter?

 

  1. Hunting for bugs. I like to add tests, and then even more tests. The time spent building tests should proportionate to the time spent building the software. Fuzzing is also fantastically useful. I love using sanitizers.
  2. Fixing bugs. Bugs disrupt user experience, compromise functionality, and can even introduce security vulnerabilities. Addressing bugs is critical to build trust in the software. 
  3.  Documentation matters. Underdocumented code is mysterious and may trigger unnecessary surprises. Lack of documentation may also harm relationships with users.
  4. Adding new features. Innovation and growth in software come from introducing new features.  Features should be user visible: ‘internal’ features are often wasteful.
  5. Improving Performance. Performance enhancement is all about making the software run faster, use fewer resources, or handle larger workloads more efficiently. This can significantly impact user satisfaction, particularly in applications where speed is paramount. Improving performance is not just about identifying bottlenecks… it is an ongoing journey. You need a good design and multiple rounds of optimizations. You can often continue to improve the performance for years and years.
However, there are areas where I believe our time is not well spent:
  • Patching code to silence false positives from disabled-by-default static analyzers. The level 4 warnings under Visual Studio when compiling C++ code is a good example, but so are the obscure GCC and clang warnings. Static analyzers are tools that can scan code for potential issues without executing the program.  However, when these tools are overly strict or misconfigured, they might report numerous false positives; issues that aren’t actually problems.  Spending time patching code merely to quiet these false alarms is, in my view, wasteful. It diverts attention from more impactful work. This is not to say that static analysis is not beneficial; when used correctly, it can save considerable time and resources. But the effort required to address non-issues can quickly become counterproductive.
  • Aimless refactoring is also often wasteful. Renaming classes, moving code around just so that it looks ‘nice’. I am not against the occasional cleaning round… but it  should not be time consuming. Refactoring for its own sake may become an excuse for not fixing bugs or for not improving the performance. It is easy work, but often not impactful.

Let us take a concrete examples. Consider the following function:

uint8_t f(uint64_t x) {
    uint8_t y = x % 256;
    return y;
}

When compiled with LLVM/clang with the -Wconversion flag, you get the following warning:

warning: implicit conversion loses integer precision: 'uint64_t' (aka 'unsigned long') to 'uint8_t' (aka 'unsigned char') [-Wimplicit-int-conversion]

The warning is bogus, a waste of time. There is no loss of precision (whatever precision means).

Another favorite of mine is this function:

uint64_t g(uint64_t x) {
    return -x;
}

Negating an unsigned integer has many applications: e.g., if you want to select only the least significant bit, and zero all others, you can use the expression (-x) AND x. Under Visual Studio, if crank up the warnings, you get

warning C4146: unary minus operator applied to unsigned type, result still unsigned
Another waste of time.
While we strive for perfection in our code, we must also be strategic about where we invest our most precious resource: programmer time. Let us prioritize what truly matters in the grand scheme of software development.

Daniel Lemire, "Programmer time and the pitfalls of wasteful work," in Daniel Lemire's blog, January 30, 2025, https://lemire.me/blog/2025/01/30/programmer-time-and-the-pitfalls-of-false-positives/.
[BibTeX]

Published by

Daniel Lemire

A computer science professor at the University of Quebec (TELUQ).

8 thoughts on “Programmer time and the pitfalls of wasteful work”

  1. Re, Patching code to silence false positives…
    As you say, it may not be worth the time it takes. And if contorted code is required, that puts a burden on future maintainers.
    I suggest, however, that adding comments explaining why the warnings do not indicate an actual flaw can save time for your inheritors.

    1. Negating an unsigned integer has many applications: e.g., if you want to select only the least significant bit, and zero all others, you can use the expression (-x) AND x.

      1. Hi
        I’m curious in what application would you select the least significant bit, versus how often would -x for unsigned be an error?

        1. Can you point at a single case in the real world where this warning identified a bug that could not be otherwise identified?

          Note that there, to my knowledge, it only exists in Visual Studio and it is highly optional (level 4 warnings).

Leave a Reply

Your email address will not be published.

You can also subscribe by email to this blog (non-commercial, no ads, weekly email).

How to post code (C, C++, Java, Python, etc.):

Wrap your code in backticks, like this:

`int main() {
    return 0;
}`