ptr = &ptr - &ptr; is completely bogus. Subtracting two pointers gives you an integer, not another pointer.
(int)0 is also bogus because 0 is already an int. So your code basically says
void *ptr = (void *)0, which just sets ptr to NULL (and the cast is redundant anyway).
I think the simplest way to get an all-bits-zero pointer is
memset(&ptr, '\0', sizeof ptr);.
nullptr doesn't give you more portability or anything; it's a workaround for a problem C++ introduced, namely outlawing implicit
void * →
Any * conversions. C is fine with defining
((void *)0), while C++ must define it as plain
0. This just means C++ will silently tolerate using NULL as a number, while C won't. It has no portability implications because the C standard says nothing about the bits of
(void *)0. See the C FAQ for more fun and exciting information.