7 ms·
I doubt your compile times were due to pattern matching which TFA demonstrates to be NP-complete, any more than C++'s compile-times are due to the undecidabilit
by yosefk 5y ago
I doubt your compile times were due to pattern matching which TFA demonstrates to be NP-complete, any more than C++'s compile-times are due to the undecidability of template metaprogramming.
(Though I guess one might argue that slow compile times on typical code and rarely-used computationally hard features have the same root cause of not treating fast compile times as a top priority.)
- tialaramex 5y agoRight, and C++ got a lot of its compiler performance for large projects by making this an embarrassingly parallel problem even though the consequences are negative for the main consumers of the code (people, not compilers). One cost of being embarrassingly parallel is the One Definition Rule. If we can compile N different code units in parallel, but they're all allowed to define things in the same namespace, obviously those definitions might contradict each other and we wouldn't notice. So, the C++ language explicitly forbids this, knowing you'll probably do it anyway, at least by mistake. If (when) you do, that isn't a valid C++ program, but the compiler isn't expected to produce any diagnostic (warning or error). So, you get a binary, but the language doesn't care what that binary does. Maybe it does exactly what you expected. Maybe it does almost exactly what you expected. If not too bad, the One Definition Rule means your compiler was fast and that's what matters.
- sakex 5y agoI usually fails at link time doesn't it?
- bluGill 5y agoNo. I have intentionally violated the one definition rule and nothing broke at all. In my case I wrote a second timer, which had hooks my unit test system could use to advance time without having to inject timers. It will fail at link time if you link everything into the same library. Even here there is an escape: there are ways to mark something as a weak symbol and than the linker won't complain about more than one definition. See your OS documentation for how this works on your implementation. (though don't be surprised if the documentation is wrong...)
- jcelerier 5y ago> No. I have intentionally violated the one definition rule and nothing broke at all. did you use LTO ? It always catches ODR issues for me. There is also GNU Gold's --detect-odr-violations switch.
- bluGill 5y agoNo. LTO is something I've been meaning to look at. Though if I can't violate the ODR intentionally I might not be interested.
- jcelerier 5y agoIf you violate ODR intentionally you are just writing code that will break in a future version of GCC / Clang / ..
- bluGill 5y agoThat is a risk I know I'm taking. Though I've been tempted to write a paper for C++ to make it defined behavior. I know it works in some form on most implementations even though it isn't legal. Thus there seems to be some other use cases for it that could/should be formalized. If anyone can give me other examples of why you want to do this and what the rules are on each platform I'll take a shot at it.
- jcelerier 5y ago> I know it works in some form on most implementations even though it isn't legal. it definitely does not, every time I had an ODR issue that caused actual bugs. For instance, dynamic_cast not working because a typeid was defined in two shared objects, etc. What would be the behaviour you expect if you have a.cpp: int constant() { return 123; } b.cpp: int constant() { return 456; } c.cpp: int constant(); int main() { return constant(); } how could you define this meaningfully other than "hard error" ? e.g. here with gcc, if a and b are put into shared libraries, the return value depends on the order in which the libraries are passed to g++ when linking. e.g. g++ c.cpp a.so b.so calls the version in a.so, while g++ c.cpp b.so a.so calls the version in b.so