Oh. And I actually do not believe it has to be a constant.
You are correct; it does not need to be a simple constant.
The text says "integer constant expression with the value 0, or such
an expression..."
Yes. (void *)(1-1) is a valid null pointer constant. So, on an
all-ASCII system, is (0x1f+(3*5)-'.'). But, in the presence of
int one(void) { return(1); }
then (one()-one()) is not - it is an integer expression with value
zero, but it is not an integer _constant_ expression. It's entirely
possible that (int *)(one()-one()) will produce a different pointer
from (int *)(1-1) - the latter is a null pointer; the former might or
might not be, depending on the implementation.