3 ms·
Posts like these really wind my stack. Basically, your response to a perfectly deterministic, compile-time-optimizable strategy for resource handling is regress
by jasonzemos 13y ago
Posts like these really wind my stack. Basically, your response to a perfectly deterministic, compile-time-optimizable strategy for resource handling is regressing to the runtime. Then hoping the overhead for not only zero-initialization, but the myriad of cmp's and jmp's and re-zero'ing for cleanup get optimized away by some data flow analysis handwavy; all of this explicit, manual labor in order to avoid the "ugliness" of RAII (don't forget any of those if's ;).
Exceptions in constructors are incredibly more useful than isValid()'s due to their composability. isValid()'s have to be checked and fail in the constructor body after the initialization list. This is why you're concluding that zero-initialization is the only way out of a problem that you're creating in the first place.
Try doing everything in the initialization list, and rely on nothing in the constructor body.
- barrkel 13y agoHow much experience have you of languages that zero-initialize before the constructor is called? I was a compiler engineer at Borland / Embarcadero on Delphi, a non-GC language with a zero-init approach. Java zero-initializes. C# zero-initializes. In fact, I struggle to think of a modern language that doesn't zero-init or prevents access to uninitialized fields by definite assignment analysis. Overhead in C++ is a different story. C++ is not low overhead enough, to me, to justify the claims made for it. For example, I like static data structures, especially in C. But in C++ they are unidiomatic. How do you statically initialize (in the rdata / rodata segment) an object graph (even as simple as a tree) with zero-copying at runtime? Or how about copy constructors that may throw exceptions. That leads to inefficient APIs for things like std::stack::pop(). Guarding against exceptions in generic code has implicit overhead when the type system is as user-mutable as C++.
- thwest 13y ago> For example, I like static data structures, especially in C. But in C++ they are unidiomatic. How do you statically initialize (in the rdata / rodata segment) an object graph (even as simple as a tree) with zero-copying at runtime? How do you do that in C? Does unidiomatic mean you can't do it? Interesting challenge. That's also an interestingly-sized data structure. Apparently big enough that the initialization time is a performance concern, but small enough to be able to lay out statically and not burden your binary size.
- colin_mccabe 13y agoHow do you [zero-initialize a structure] in C? Does unidiomatic mean you can't do it? Interesting challenge. You can zero-initialize an object on the stack in C like this: struct my_object obj = { 0 }; Everything in the structure, no matter what it is, will be 0. Longs will be 0, shorts will be 0, pointers will be null, etc. In C++, you can still do this, but only for POD types. Basically, in C++, it is assumed that you will manually initialize all data members in the constructor. POD objects get a free pass since they're essentially C structs.
- ajross 13y agoPre-cooking complicated data in C programs such that it can be faulted in with zero initialization time at runtime has been an idiom for a long time. Try building GNU emacs. It's true that the language support for generating such a thing is minimal (though templates in C++ can get you pretty far), so other techniques like generating code at build time or (the emacs trick) actually executing the script interpreter in a bootstrap mode to generate the pickled data are common.
- pcwalton 13y ago> Then hoping the overhead for not only zero-initialization, but the myriad of cmp's and jmp's and re-zero'ing for cleanup get optimized away by some data flow analysis handwavy To be fair, with move semantics in C++11, C++ has started to depend on dataflow optimizations for zero-initialization (or, to be more precise, zero-deinitialization). After a value is moved, typical objects will zero themselves out so that the call to the destructor won't do anything, and they count on data flow analysis to strip out the zeroing out and the overhead of the destructor call. (That said, I much prefer definite assignment analysis to zero-initialization. I tend to think zero values in general are kind of a wart in language design.)