On 2/1/2016 5:47 PM, Rob Stewart wrote:
I mean, is the default initialization of std::vector to the empty state no more correct than leaving it uninitialized? Should we require programmers to explicitly set the vector state, even if they want to start off with an empty vector?
That's not what I asked you about. I asked if you provided a way to construct your types without initializing the data. I thought it was obvious that I was asking about a constructor overload taking an instance of, say, uninitialized_t as the mechanism. That is, one would create an instance from an argument named, say, "uninitialized."
Sorry, I'm confused. In this post I was responding to what Steve said. I wasn't trying to respond to your question. Although I guess they're related. And it may be my shortcoming, but it actually wasn't obvious to me that you were asking about "a constructor overload taking an instance of, say, uninitialized_t as the mechanism". Is that mechanism preferable to mechanism of having separate, compatible classes I proposed (in both the reply to Steve's post and the reply to your post)? I haven't completely thought it through, but I might've thought that solution of having separate types might be preferable if only for convenience reasons because you wouldn't have to pass any arguments to get an uninitialized variable. And, as Steve pointed out, if you choose to use a type that requires explicit initialization before use, it may help catch some bugs (in debug mode). But now that you've spelled it out for me, having a single class with a separate constructor also seems appealing because then there would definitely be no compatibility issues between separate classes. But then again, there may be issues other than just default initialization to consider. For example, what if we wanted an option to disable run-time range checking when converting between different (sized) integer types? Keeping the one class and adding an extra constructor for that wouldn't really work. Because you'd just be substituting one run-time check for another, right? But another separate compatible class might work. And how about range checking on arithmetic operations? Is that too many options? Should we just not provide for those options?
Or is the empty state somehow intrinsically valid, but the zero value for integers is not?
Zero may be a valid value with semantics different than "not set." An empty vector doesn't have a magic value that means it's actually empty.
Just to be clear, I wasn't being sarcastic or anything. I'm just trying to think this through. So I agree that zero should not be interpreted as a "magic" value indicating "value not set". In my reply to Steve I suggested that the integer class for example, might, in debug mode, contain an extra bool member indicating whether or not the value had been explicitly set. And default initialization would set that bool to indicate that the value hadn't been explicitly set. What I am suggesting is that, perhaps, the std::vector people decided not to provide for uninitialized vector construction because a) they suspected that conditional initialization would be a small portion of all initializations and that the default empty state would be a fairly large portion, and/or possibly b) the compiler optimizer would deal with the redundancy in a significant portion of those conditional initializations, and/or c) the cost of the program being non-deterministic if a programming error slips by is unacceptably high. (I think reason c) is the main one to most of us who desire default initialization.) And it's not obvious to me that those reasons don't apply to integers as well. With respect to the proportion of all initializations that are conditional, the only way we could know that is to do a large random sampling of code on github or whatever. I actually googled to try and find out if anyone had done such a sampling, because I'm actually quite curious what the answer would be. My googling was not successful. I know I'm not always great at expressing my ideas in writing, but if you have time to reread my reply to Steve, in it I suggest a solution in which three separate compatible classes would be available. Each with a different policy for default initialization and requirement for "explicit set before use". Do you still prefer the single class with an extra constructor for "uninitialized construction" solution to the one I proposed?