7 ms·
Very dubious stuff here. For example: > and it's the only C++ feature that has a runtime cost even if you don't use it – sometimes as additional hidden code at
by zabzonk 6y ago
Very dubious stuff here. For example:
> and it's the only C++ feature that has a runtime cost even if you don't use it – sometimes as additional hidden code at every object construction, destruction, and try block entry/exit, and always by limiting what the compiler's optimizer can do, often quite significantly.
C++ doesn't do "hidden code" - "if you don't use a feature you don't pay for it" is one of the bedrock principles of the language.
- david2ndaccount 6y agoThat’s just marketing. See: https://godbolt.org/z/q9zEj4 https://godbolt.org/z/q9zEj4 With exceptions turned on there’s a hidden call to _Unwind_Resume. Additionally, the destructor has to be duplicated.
- microtherion 6y ago"you don't pay for it" doesn't mean that no code gets generated for exceptions in this case, but that no code gets executed unless an exception gets thrown, and your example does not disprove that.
- arcticbull 6y agoGenerated code has a cost in terms of size, of course, and in terms of performance via the addition of branching, branch mis-prediction penalty and decreased cache locality. This function invocation will also of course flush the pipeline and harm inlining. On a hot path this could be non-trivial.
- kllrnohj 6y agoWhile true it's also fewer branches than manual error handling via return values. So the only "fast" option is to just not handle errors at all. Which is a terrible recommendation, of course.
- alisonkisk 6y agoThat not the point, though. The point is that the cost is invisible with exceptions. For example, there could perhaps be an alternate version of C++ where every function is required to declare whether it could throw an exception (and a very smart compiler proves where it's possible), or that -fno-except flag is inverted so you have to opt in to exceptions.
- jcelerier 6y agoyou still have branches with noexcept, the difference is that they call std::terminate in case of stack unwinding.
- asddubs 6y agoI don't agree with the article but this is actually true, exceptions and RTTI are the two exceptions to the zero overhead principle. if you don't use -fno-exceptions (or mark the function as noexcept), every function will generate additional instructions to deal with potential exceptions happening https://en.cppreference.com/w/cpp/language/Zero-overhead_principle https://en.cppreference.com/w/cpp/language/Zero-overhead_pri...
- junon 6y agoThis is false. Most code emitted by modern compilers incurs no overhead for exceptions except for when they are actually thrown. This is a historical rule that is no longer true. https://stackoverflow.com/a/13836329/510036 https://stackoverflow.com/a/13836329/510036
- asddubs 6y agoI don't think it really contradicts what I said, I didn't say extra instructions were executed on each function call, just generated. I guess it depends on how you define overhead, but if you compile a program that does not use exceptions with exceptions on, it will run slower if you benchmark it. That being said, I do use exceptions and think they're obviously worth it, but there is an overhead to them, even if it's not as simple as "x additional instructions are executed"
- nzmsv 6y agoThat would be one strange benchmark then. It would have to be benchmarking something other than the code in question. Simple analogy: let's say you have a program that has 10 functions in it. You write a benchmark that exercises one of these and never (no, not once, never) calls the other functions. The other 9 are truly dead code. Would you expect the benchmark result to be different between that and a program that only included the one function being benchmarked?
- asddubs 6y agoyes if the generated code causes e.g. more cache misses and branch mispredictions, which additional instructions inbetween the executed ones will
- dfox 6y agoThe issue there is interaction between exceptions and deterministic destructors. In the end it means that there has to be some hidden code for every stack allocated object whose destruction could be skipped over by exception handling mechanism. There are various way to implement that, but all of them involves something that is "hidden code" and also the mythical "overhead for feature you don't use". Another giant issue with C++'s "if you don't use a feature you don't pay for it" and interactions of various features with each other is that features you do use tend to be horribly expensive. It seems to me that authors of C++ tend to use some antiquated model of what "runtime cost" means which totally ignores effects of cache locality and code size.
- sideeffffect 6y agoI'm not a C++ developer, but AFAIK the fact that C++ is not 100% "you don't pay for what you don't use" is commonly acknowledged. Exceptions are an example of that. There are ideas/proposals how to fix that: https://www.youtube.com/watch?v=ARYP83yNAWk https://www.youtube.com/watch?v=ARYP83yNAWk