You can't have an array of size 0, in the sense that every array type includes the number of elements as part of the type, and for the type to be well defined, the number of elements must be strictly positive. Part of the reason for this requirement is to be able to guarantee that sizeof(x) is nonzero regardless of the type of x.
So your second example is not well-formed, although I imagine there might be a compiler out there that accepts it.
Your first example, on the other hand, is fine. There is nothing wrong with using "new" to create a pointer to "the first element" of a 0-element dynamically allocated array. Of course, that first element does not exist, so the pointer is an off-the-end pointer for that array. It's a valid pointer; it's guaranteed to be distinct from other pointers; and you should delete it at some point if you wish to avoid memory leaks. What you can't do is dereference it, because it doesn't point to an element. That's true of any off-the-end pointer, not just this one.