Hacker News new | ask | show | jobs
by jessermeyer 1459 days ago
Ah, so it's the nil address?
3 comments

The address of the nil byte + 1
But isn't `""` 0 terminated? So the first offset past the nil byte is 0, interpreted as an address.
"" is empty, so ""[0] is the nil byte.

The code uses "" as an arbitrary address, and ""[1] as that address + 1.

This way this-"" gets you 1-based index into the array.

It assumes the compiler dedfuplicates strings, making the behavior of this program undefined.

No, it's the address past the end of the array {'\0'}.
Mind to unpack that for me?

Here's how I unpack this: ""[1] is the 0 (termination) byte. The 0 byte is then interpreted as an address -- the nil address.

But what's the use of asking for the address of the null terminator? Where is that stored exactly?

The "" will define a null terminated char array to represent the string. But as it string contains no text it's a char array that only requires one byte (i.e. it contains nothing but the null termination character).

Now the first character of that char array is found here: ""[0]

The second character is found here: ""[1]

So the address of the second character is found here: &""[1]

But as the string was represented by one byte char array that second address is past the end of the string.

So it's actually an undefined address.

Nit: one past end of an array is actually fine as an address.
Not always. Consider this 'test.cpp' example:

    #include <stdio.h>
    #include <string.h>
    
    struct a_struct {
      char a[1];
      char b[2];
    
      a_struct() {
         strcpy(a, "");
         strcpy(b, "b");
      }
    } x;
    
    int main() {
       printf("before:\n");
       printf("a : '%s'\n", x.a);
       printf("b : '%s'\n", x.b);
    
       char *c = &1[x.a];
       *c = 'c';
    
       printf("after:\n");
       printf("a : '%s'\n", x.a);
       printf("b : '%s'\n", x.b);   //b is now corrupt
    }
Compile and running this code:

    C:\temp>g++ test.cpp
    C:\temp>a.exe
    before:
    a : ''
    b : 'b'
    after:
    a : ''
    b : 'c'
Yes, dereferencing past the end is not fine, but the address itself is.
""[1] is not the termination byte, it's the byte after that.

Its address is taken there with &, which yields a const char*. The (char *) cast is only there to cast away const.

The evilest way to write `nullptr`.
it is not nullptr, it is address past \0 in "", which is an invalid address
No, the address itself is not invalid, you're just not allowed to dereference it. Pointers have to point at a valid object or, in the case of arrays, one past the end of the array. It's what `std::end` returns
Hence, evilest. (It got me.)