I looked at the (draft) standard and I couldn't find anything that explicitly prohibits this. I would guess that the answer is "no", though. This is why:
- As you say, new is required to return a non-null pointer.
- Further, whatever it returns must be safe to pass to delete.
- So a "random value" won't work because it will break delete.
- It's also required to return different values for each call (at least until they are deleted) - see the C++ standard section basic.stc.dynamic.allocation.
- At this point only one option remains: return "fake pointers" which are somehow recognizable by delete as "fake pointers".
One possible implementation could be done by reserving a range of unpaged memory, and every time someone calls new int[0] it could return a different address in that range (easy to do if the allocator keeps a global counter or something like that).
On the plus side, you will gain the ability to immediately detect dereferences on this type of pointer. On the other hand, you will lose the ability to detect double-frees because delete on your pointer effectively becomes a no op, and you will make new and delete more complex and slower for all the normal cases.
So because it's tricky to do, and the cons outweigh the pros, I'm pretty confident that nobody does that.
gcc on linux just allocates a small amount of memory and returns that. I believe that this is pretty much a standard way to do this.