问题
In one of the comments in this question, it was brought out that initializing C++ pointers by default would break compatibility with C.
That's fine, but why would something like this matter? I would think the only time it would actually matter is if I wanted an uninitialized pointer for some reason. But I can't think of a reason why I would want to have that.
Is there a use for uninitialized pointers? Or is the compatibility issue merely one of compatible behavior (i.e., not increasing overhead) and not one of breaking code?
回答1:
This is a very specialized optimized case for Video Games (basically an embedded system). We used to use them for Load-In-Place data behavior in our Video Games to speed up loading (and avoid fragmentation).
Basically we would create console-side (Playstation) objects in a PC cooker. Then to reduce fragmentation overload, we would pack the data objects in a contiguous buffer with a single alloc. References to the data objects in this buffer would then be changed to subtract the base from pointers to offsets (unfix call -- we also had a virtual fix / unfix calls that took the buffer base and could convert between offsets and pointers).
When we loaded the data, it loaded in one large block. All data referenced by the root was off the root object. We could do an inplace "new" on the the root that would initialize the proper VF tables for the object and fixup all the attached blocks (by doing inplace new and then fixing up attached blocks respectively).
We needed the constructors called (in place new) to generate the proper VF-Tables in the objects. However, if the pointers were automatically cleared to NULL during the constructor, we would have lost the offset data and not been able to recreate the pointers between the objects within the contiguous block.
FWIW, this is a common technique in the Video Game world. This Gamasutra article (not written by me or my coworkers) explains in detail the similar thing they did at another company:
Also, this topic of discussion on SourceForge.
There have even been several GDC (Game Developer Conference) talks on the subject.
Searching on Google for "load-in-place" will give many other examples of people using this technique that basically requires uninitialized pointers.
NOTE: Currently, this is the only response that actually answers the question asked ("Is there a use for uninitialized pointers in C or C++?") by giving a specific use for pointers that must remain unitialized.
All the other responses are better answers for the original question referenced ("[C++] Why aren’t pointers initialized with NULL by default?") that caused the poster to ask this question.
回答2:
First of all, initializing pointers (or any other variables) by default does not break compatibility with C. Both C and C++ state that a value of uninitialized variable is indeterminate; in practice, this means that it can hold any value (including a trap representation), but note that 0
belongs to the set of "any values"! So a conformant implementation can perfectly well initialize all pointers to 0
. Your program, should it rely on that, would not be conformant, however.
Now as to why you may want your pointer to not be initialized: mainly when it is written to afterwards. For example:
void foo(int*& p) {
p = new int;
}
int* p; // why initialize? we overwrite it anyway
foo(p);
You can say that compiler should be able to optimize this away. Unfortunately, it cannot do so if the definition of foo
is not available (e.g. global link-time optimizations are disabled; or they are enabled, but the function is in a DLL), since it doesn't know if foo
will try to read from p
(and then initialization would be needed), or if it would just write to it (and then initialization isn't needed). What more, there may be cases that are harder to analyze; for example:
bool try_parse_int(const char* s, int& n)
{
// if parsed successfully, assign result to n and return true
// if there was error parsing, don't touch n and return false
...
}
int n;
if (try_parse_int(s, n)) {
// use n here
...
} else {
// don't use n here
...
}
This one is much harder for the compiler to analyze even if it has full definitions of all functions.
回答3:
Initializing a pointer takes some time. Most of the time you shouldn't care about that, but there are rare occasions when it would make a difference. One of the guiding principles of C (and by extension C++) is never make you pay for something you might not need Don't pay for what you don't use.
Another rare case might come up in embedded programming, where a variable corresponds to a hardware register. Putting a value in the register will start the hardware performing some action which might be detremental.
回答4:
Use for an unitialised pointer? See std::strtol().
char * bad;
long n = std::strtol( "123xyz", &bad, 10 );
after this call, bad will contain a pointer to 'x'. There is no point in initialising it.
回答5:
If you were to write a C style program in C++ but assumed pointers were initialized, then took that program back to a C compiler, it would fail to work. That's the only reason I could imagine it mattering.
回答6:
It wouldn't break compatibility with C - a C implementation in which all unintialised pointers are actually initialised to 0 (or indeed, to anything at all!) would be perfectly conforming.
回答7:
Not having to pay for what you don't need is not here for compatibility with C. It's one of the most important principles of C++ too.
回答8:
An uninitialized pointer is useful for one thing, and one thing only: Assigning something to it. The only reason you'd ever want one is that you don't have a fixed initial value, but plan on assigning one at some point in the future, and thus initializing it is a waste. You could assign it to NULL, if you wanted, or something else.
Since in C++ you can declare variables anywhere in a scope, and not just the start, this is no longer really relevant, since you could just declare it where you use it.
The short answer, though, is no. Just assign it to NULL.
回答9:
I'm not sure what comment you're talking about, but I think it only breaks syntactical compatibility. There's no use of uninitialized pointer, but there's also no use to initialize it before you know the value you want to put in there and we don't want to waste time on it.
回答10:
Suppose you have a function that is an interrupt handler that requires a lot of pointer stack variable(s):
void interruptHandler()
{
char* ptr0;
...
char* ptrX-1;
char* ptrX;
}
Suppose its crucial you get in-and-out as fast as possible. You don't want to waste any needless time initializing to defaults, you know you'll try to be safe setting your pointersto something valid later.
来源:https://stackoverflow.com/questions/1911117/is-there-a-use-for-uninitialized-pointers-in-c-or-c