C programmers start the day a bit later, keep using the language in the evening, and stay up the longest. This suggests C may be particularly popular among hobbyist programmers who code during their free time (or perhaps among summer school students doing homework).
... or they're the only ones stuck down a rabbit hole chasing some obscure memory leak that keeps bugging them until late in the evening.
Naively, there's nothing forcing these developers to chase that leak into the night, rather than into the next work-day.
But I do wonder whether some languages have debugging problems that require "keeping more state" to solve them than others, such that the developers doing debugging in those languages would rather forge ahead and finish, than drop it and pick it back up the next day. That'd be an interesting thing to measure.
It'd also be interesting if some languages attract certain developers, because the attention-span and "mental stack size" the language designers assumed for the language, feel better suited to them. Maybe there are languages better for people who can juggle many or few facts at once; languages better for people who can hold three screens of text in their head, or who prefer to only have to think about one line at a time; etc?
There's definitely the overhead in re-loading where you were yesterday, although sometimes that's handy - "sleeping on it" does work.
I find (in any work, not just the rare C work) that when I get into a juicy problem I just don't want to stop. It's nothing to do with the task switching / reload cost, it's that I'm interested in what I'm doing.
So I think you're right that it's about what kind of developers a language attracts, but not because it effects the language designers. I think it has something to do with the languages used by people along the "programming is a job" - "code is life" spectrum. Look at Haskell's bump. AFAIK, Haskell is only used by people for whom code is a way of life.
(This is not an endorsement or indictment of either end of that spectrum. Some people who paint are workers, others are craftsmen, others are artists. All use paint.)
I started leaving my laptop hibernated with visual studio or gdb stuck at the break point where I was off. The feature to anottate variables and pin them also helps for when somebody bothers you mid debug session.
> But I do wonder whether some languages have debugging problems that require "keeping more state" to solve them than others, such that the developers doing debugging in those languages would rather forge ahead and finish, than drop it and pick it back up the next day.
I used to stay late at work sometimes for this reason - not more than an hour or so but I found that even when I stayed late I often didn't manage to solve the issue that day - instead I came in the next morning fresh and was able to solve it better after having slept on it.
Now, that's true of debugging in my experience, but if you're knocking something out quick and don't want to have to get back into that groove the next day, it's a different story.
Use address sanitizer and leak sanitizer (-fsanitize=address). Compile with options that forbid omission of frame pointers (-fno-omit-frame-pointer) to get a nice backtrace of where the allocation occurred. Also compile with full debugging info (-g) so that leak errors contain file and line numbers. Problem solved.
EDIT: this apparently only works on x86-64 Linux. If you are targeting something else, it might be slightly harder.
You forgot "bypass or instrument our custom allocators", "determine repro steps in the first place", "filter out false positives", "bypass or instrument your refcounting - because failing to pair a free() with your malloc() isn't the problem, nor even failing to pair decRef()s with addRef()s - breaking up cycles is", etc.
Sometimes the answer is "force your scripting language to garbage collect again".
Sometimes the answer is "track down an incorrect cast in code that ultimately causes a single byte corruption in your refcount".
Unless you're working in the embedded space, there's no reason to not write your C project to target whatever arch is the most debug-friendly first, and then just port it to the system it's "for" at the end.
Valgrind is a serious savior for me sometimes, it's able to catch leaks, access violations, use of uninitialized memory, use-after-frees (and it can tell you where it was free'd), data races, etc. Microsoft's heap debugging stuff really doesn't measure up unfortunately, on Windows I'm frequently left grinding my face into the ground when I hit such issues. Fortunately they're fairly rare as I generally stick to C++ with more modern techniques which avoid most of the pitfalls - but when they do happen it can get nasty without a tool like Valgrind.
Valgrind misses certain problems with stack memory and runs your program with a 10x slowdown. AddressSanitizer and friends use a lot of extra virtual address space, but run with about a 2x slowdown.
If you're interested in C++ tooling, maybe watch through The Care and Feeding of C++'s Dragons[1] from GoingNative 2013. They start to talk about AddressSanitizer at 55m40s, but the entire thing is really good. The tools they talk about have just gotten even better and more widely available since then.
Interesting, what I'd heard from a colleague is that asan wasn't worth using since it couldn't catch uninitialized memory and stuff. Thanks, I'll have to look into it more.
AddressSanitizer is part of a suite of tools - MemorySanitizer will catch uninitialized memory, and there is UndefinedBehaviorSanitizer and ThreadSanitizer as well. Your colleague may be complaining that a wrench is not a screwdriver.
Address sanitizer has caught something on every codebase I've enabled it on. YMMV, but I encourage you to at least try it out and draw your own conclusions.
What slows me down in C is not memory bugs, its bare-bones nature, which leaves me either implementing basic stuff myself or trying integrate some library that I don't really want.
Memory unsafety is terrifying, but not much of a time-sink in ordinary development. Only once in my career have I found a memory bug that was difficult to track down and fix (it was a stack overflow in a C++ program on an embedded OS).
The real problem with memory unsafety is that I nave no idea how many memory bugs I didn't find.
Valgrind a lot both with finding and diagnosing memory bugs. But it cannot solve everything.
for my sideprojects i use mostly C because it is easy and straightforward - you just write what you need without satisfying all the other requirements. At work it is Java, C++, Python.
I had a boss that called while I was on vacation and told me he needed me back in the office immediately to fix a bug that was only in development. Long of it was, I stayed on vacation for an extra week to fix the bug remotely, but when he called I was in the car about a half hour from the Canadian border in Washington after having driven from Chicago.