4 ms·
> Visual Studio has an unofficial command line option to help identify certain classes of IFNDR I'm sure there's a good reason why this is hard, but I'm a litt
by TillE 2y ago
> Visual Studio has an unofficial command line option to help identify certain classes of IFNDR
I'm sure there's a good reason why this is hard, but I'm a little surprised that this isn't caught by static analysis. Sure enough, I can't get MSVC Code Analysis to complain about the example with different inline functions.
- tialaramex 2y agoFor the One Definition Rule specifically, sure, the tools could just be better, it would be extremely difficult in C++ but this entire problem doesn't arise in many languages. However a bunch of IFNDR in C++ covers cases where Rice's Theorem applies, so your static analysis cannot help. Rice says that if you language has non-trivial semantic requirements (not just syntactic ones) that's Undecidable, which means there cannot be any algorithm which always says whether any program does or does not satify the requirement. C++ is reluctant to lose any programs which might potentially satisfy its requirements, so instead it chooses to say that they must compile unless the compiler can prove they do not, which by Rice we know cannot be 100% effective. In practice, why even bother? Many compilers don't put much work into trying, it might help users but it's not a compliance requirement so it's often not a priority. Rust's choice here (thus avoiding IFNDR) is to reject programs unless it can show that they meet the requirements. Even if you can convince a PhD team that your program satisfies the requirements, that won't help, rustc needs to be convinced or it won't compile. Unlike C++ the incentives here are aligned, that's what Rust's "Non-lexical lifetimes" change was about - the compiler got smarter, allowing previously unacceptable Rust to compile.
- rbanffy 2y ago> Rust's choice here (thus avoiding IFNDR) is to reject programs unless it can show that they meet the requirements. I wonder if a C++ compiler that does that would be feasible. A lot of this check avoidance is due to the expense of compilation when the language was created (and, back then, C++ itself was sometimes considered prohibitively expensive). The Rust compiler is slow because it’s doing a lot of work (the same reasoning applied comparing C++ to C - and C++ started as a transpiler compiling C++ to C first.
- tialaramex 2y ago> The Rust compiler is slow because it’s doing a lot of work (the same reasoning) [...] This is commonly assumed but the evidence suggests otherwise. The borrowck for example is not a large fraction of the compiler runtime. So if you've just assumed this is correct, rather than you've collected evidence, I suggest your foundational argument needs re-evaluating. As to the idea that you can assess C++ instead, not really, you need invasive language changes, Sean Baxter's "Circle" compiler provides a whole bunch of experimental features including his take on borrow checking, but you can't meaningfully check existing C++, it just gets rejected, you have to write your new checkable C++ instead.
- rbanffy 2y ago> you have to write your new checkable C++ instead. That was more or less where I was going. Existing code is mostly hopeless, so, maybe, a dialect that makes more of the developer’s intentions explicit would provide enough for more checking. I don’t have evidence that Rust’s checking is why it’s slow, but I assumed it was a good guess.
- tialaramex 2y agoI think I'd have guessed similarly, but then I read the data. I don't think a C dialect is a good idea. You want a blank slate, on which you can begin with your foundational concerns (e.g. constant time evaluation) rather than starting from C. There may be practical reasons to prefer how C spells things, the way Rust looks like a semi-colon language even though it's mostly an ML, but the core language isn't helpful.
- rbanffy 2y agoThe C dialect idea would be useful if you wanted to gradually take a code base in. You’d mark parts of it as unsafe/unchecked and new code could come in using the new constructs with a more convenient syntax.
- layer8 2y agoOne reason for this is separate compilation, and linkers not being required to perform that level of static analysis, besides them lacking the necessary information about (e.g.) inlined functions or struct layouts. Note that in case of shared libraries (DLLs, .so), the OS loader/linker would have to perform that analysis.
- plorkyeran 2y agoLinkers could require that all definitions of inline functions be byte-for-byte identical, but in practice people expect to be able to use libraries that were not built with exactly the same compiler binary. Any check looser than that is trying to determine if two bits of machine code are sufficiently equivalent, which is distinctly not easy. Static analyzers tend to be structurally unable to detect ODR violations - either they only analyze one translation unit at a time, or their cross-module analysis itself relies on the ODR being obeyed.