Original Question
(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 */
}
List of allowed operations:
(To be completed and corrected by your answers and comments.)
- Well defined: Take the size of the pointer variable. E.g.
sizeof(ptr)
- Well defined: Take the size of the dereferenced pointer (given it is not
void *
). E.g.sizeof(*ptr)
(see comments of EOF and Jonathan Leffler ). - Well defined: Assignment of another (valid) value to the pointer (not to the referenced variable!). E.g.
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 */
Operations that are not well-defined according to the standard:
(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:
- Undefined: Comparing the value of the pointer (even to a NULL-Pointer constant)
- Undefined: conversion to an integral value
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.