Reputation: 601
(please see "Edit: Updated scenario")
This question might be a duplicate in one or another way to a huge collection of questions around undefined behavior of pointers to objects that gone out of scope etc. But all questions I found here to this topic are mostly specialized use cases. So I would like to spin the question upside down, not asking if something is forbidden, but WHAT exactly is allowed?
To have a possible scenario: You have a function, that takes a pointer - you don't know if it came from a (still) valid object. Which operations are under all circumstances NOT undefined behavior? Which might have unspecified side conditions?
int * myFunc(const int * const A, int * B)
{
...
}
Edit: Updated Secenario
In the comments to the question and Matt McNabbs answer it was pointed out that UB has risen most likely anyway, as an invalid pointer(s value) is used during call the function in the scenario. Therefore I will change the scenario a little (following the example from Keith Thompsons answer):
int *ptr = malloc(sizeof *ptr);
/* the value of ptr is now valid, possibly NULL */
if (ptr != NULL)
{
/* the value of ptr is valid and non-null */
free(ptr);
/* the value of ptr is now invalid */
... /* here operations in question */
}
(To be completed and corrected by your answers and comments.)
sizeof(ptr)
void *
). E.g. sizeof(*ptr)
(see comments of EOF and Jonathan Leffler ).ptr = NULL;
Well defined: Accessing the representation of the Pointer (example from Keith Thompson's answer):
unsigned char rep[sizeof ptr];
memcpy(rep, &ptr, sizeof ptr); /* ok, accesses the representation */
/* but not the value */
(To be completed and corrected by your answers and comments.)
These operations are often treated as if they are well-defined on an invalid pointer, but are not well-defined according to the standard:
As with all undefined behaviour, you may get away with (ab)using the pointers on many machines, but the C Standard does not guarantee that you will get away with and there are (or once were) machines where such abuse of a pointer would lead to programs failing dramatically.
For the general rule, see Keith Thompson's answer — and the extensive comments below.
Upvotes: 1
Views: 186
Reputation: 141586
This question is very broad. But to answer your specific scenario:
int * myFunc(const int * const A, int * B)
If this function were called with an invalid pointer value then it already caused undefined behaviour by evaluating the invalid pointer value as part of preparing to call the function.
All of your bullet points "well defined" are not well defined, since once UB has happened the cat cannot be put back in the bag.
Upvotes: 1
Reputation: 263277
Any use of an invalid pointer value has undefined behavior.
int *ptr = malloc(sizeof *ptr);
// the value of ptr is now valid, possibly NULL
if (ptr != NULL) {
// the value of ptr is valid and non-null
free(ptr);
// the value of ptr is now invalid
ptr; // UNDEFINED BEHAVIOR
}
Citation: N1570 6.2.4p2:
The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.
It's likely that a compiler will generate no code for the expression statement ptr;
; that is, of course, within the bounds of undefined behavior.
Any operation on the pointer object that doesn't retrieve its value is (at least potentially) well defined:
sizeof ptr; // ok, doesn't use the value
sizeof *ptr; // ok, doesn't use the value, only the type
ptr = NULL; // ok
You can also access the representation of the pointer object without accessing its value:
unsigned char rep[sizeof ptr];
memcpy(rep, &ptr, sizeof ptr); // ok, accesses the representation
// but not the value
though there's not much you can do with the result.
Upvotes: 5