Earlier quoted context omitted.
This is fixed by the suggestion right before it: > * Reproducible builds. The sanity you save will be your own. Pro-tip: wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable. The sanity you save will be your own. Upgrading compiler versions shouldn't be done out-of-band with your normal PR process.
I agree that this helps, although I still think that in general, the default build should never do -Werror, since people may use other toolchains and it shouldn't surprise-break downstream (I'm pretty sure this is a problem Linux distros struggle with all the time..) If it does it only in your fully reproducible CI, then it should be totally fine, of course.
You've just inherited a legacy C++ codebase, now what?
181–190 of 356 posts
Re: You've just inherited a legacy C++ codebase, now what?
#182Earlier quoted context omitted.
I'm not hardcore on auto-formatters, but I think their impact on code history is negligible in the case of every legacy system I've worked on. The code history just isn't there. These aren't projects that used git until recently (if at all). Before that they used something else, but when they transitioned they didn't preserve the history. And that's if they used any version control system. I've tried to help teams wh…
SVN was a thing by the mid-2000's, and history from that is easy to preserve in git. Just how old are the sourcebases in question? (Not to shoot the messenger; just like, wow.) edit:typo
Re: You've just inherited a legacy C++ codebase, now what?
#183Some good advice here, and some more...controversial advice here. After inheriting quite a few giant C++ projects over the years, there are a few obvious big wins to start with: * Reproducible builds. The sanity you save will be your own. Pro-tip: wrap your build environment with docker (or your favorite packager) so that your tooling and dependencies become both explicit and reproducable. The sanity you save will be…
Step 0: reproducible builds (like you said) Step 1: run all tests, mark all the flaky ones. Step 2: run all tests under sanitizers, mark all the ones that fail. Step 3: fix all the sanitizer failures. Step 4: (the other stuff you wrote)
Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile"
Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link.
Then you used to discover that Win7's app compat db expected a "real" timestamp, and a hash just won't do. (Thank God, that's dead now). This is usually the part where you start questioning your life choices.
Then somebody comes to your desk and asks if you can also make partial rebuilds deterministic.
On the upside, step 1 is usually quick, there will be no tests.
Re: You've just inherited a legacy C++ codebase, now what?
#184Structure101 is the best way to grok the architecture er tangles of a large code base. They have a trial period that would give you the overview, but their refactoring support is fantastic (in Java at least).
Re: You've just inherited a legacy C++ codebase, now what?
#185 * You can find out the most relevant files/functions for your upcoming works. If some functions/files have been frequently changed, then it's going to be the hot spot for your works. Focus on them to improve your quality of life. If you want to introduce unit tests? Then focus on the hot spot. Suffer from lots of merge conflicts? The same.
* You can also figure out correlation among the project and its source files. Some seemingly distant files are frequently changed together? Those might suggest an implicit structure that not might be clear from the code itself. This kind of information from external contexts can be useful to understand the bird's eye view.
* Real ownership models of each module can be inferred from the history. Having a clear ownership model helps, especially if you want to introduce some form of code review. If some code/data/module seems to have unclear ownership? That might be a signal for refactoring needs.
* Specific to C/C++ contexts, build time improvements could be focused on important modules, in a data driven way. Incremental build time matters a lot. Break down frequently changed modules rather than blindly removing dependencies on random files. You can even combine this with header dependency to score the module with the real build time impact.
There could be so many other things if you can integrate other development tools with VCS. In the era of LLM, I guess we can even try to feed the project history and metadata to the model and ask for some interesting insights, though I haven't tried this. It might need some dedicated model engineering if we want to do this without a huge context window but my guts tell that this should be something worth try.Re: You've just inherited a legacy C++ codebase, now what?
#186Earlier quoted context omitted.
The scripted, packaged docker with toolchain dependencies and _is_ the build. If someone decides to use a different toolchain, the problems are on them.
Yeah that works if you are not dealing with open source. If you are dealing with open source, though, it really won't save you that much trouble, if anything it will just lead to unnecessarily hostile interactions. You're not really obligated to fix any specific issues that people report, but shrugging and saying "Your problem." is just non-productive and harms valuable downstreams like Linux distributions. Especiall…
For some things the tradeoffs are much less clear, open-source or not e.g. a complex multi-platform GUI application. If you're going to ship a Flatpak to Linux users for example, then the utility of allowing any random build environments is not so clear; users will be running your produced binaries anyway. These are the minority of cases, though. (No, maybe not every user wants a Flatpak, but the developers also need to make decisions that balance many needs, and not everything will be perfect.)
Half of the problem, of course, is C and C++'s lack of consistent build environments/build systems/build tooling, but that's a conversation for another day.
That said, I generally agree with you that if you want to be a Good Citizen in the general realm of open-source C and C++ code, you should not use -Werror by default, and you should try (to whatever reasonable extent) to allow and support dependencies your users have. And try to support sanitizers, custom CFLAGS/CXXFLAGS, allow PREFIX and DESTDIR installation options, obey the FHS, etc etc. A lot of things have consolidated in the Linux world over the years, so this isn't as bad as it used to be -- and sometimes really does find legitimate issues in your code, or even issues in other projects.
Re: You've just inherited a legacy C++ codebase, now what?
#187Earlier quoted context omitted.
Step 0: reproducible builds (like you said) Step 1: run all tests, mark all the flaky ones. Step 2: run all tests under sanitizers, mark all the ones that fail. Step 3: fix all the sanitizer failures. Step 4: (the other stuff you wrote)
Step 0 sounds so easy. Until you realize __time__ exists. Then you take that away, and you find out that some compiler heuristics might not be deterministic. Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile" Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link…
Re: You've just inherited a legacy C++ codebase, now what?
#188Earlier quoted context omitted.
Step 0 sounds so easy. Until you realize __time__ exists. Then you take that away, and you find out that some compiler heuristics might not be deterministic. Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile" Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link…
I think (well, assumed) what they meant by deterministic builds was merely hermetic builds, which are easier. True determinism is overkill for step 0.
But yes, if the goal is "slap it all in a container", that's probably good and at least somewhat reproducible. We aren't Python here! ;)
Re: You've just inherited a legacy C++ codebase, now what?
#189I enjoyed the article and learned something. But I've been wondering: When people say "rewrite in a memory-safe language", what languages are they suggesting? Is this author rewriting parts in Go, Java, C#? Or is it just a smirky, plausibly deniable way of saying to rewrite it in Rust?
Re: You've just inherited a legacy C++ codebase, now what?
#190My first thing is usually: #0: Replace the custom/proprietary Hashmap implementation with the STL version. Once upon a time, C++ academics brow beat the lot of us into accepting Red-Black-Tree as the only Map implementation, arguing (in good faith yet from ignorance) that the "Big O" (an orgasm joke, besides others) worst case scenario (Oops, pregnancy) categorized Hash Map as O(n) on insert, etc. due to naieve imple…
> worst case scenario (Oops, pregnancy)
> (of Waat? A Preggers Table Bucket?)
> "Big O" notation (which is demonstrably a sex-humor-based system
This post reeks of obesity, desperation, poor life choices, and old-fashioned body odor.