What is this?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Eric

    What is this?



    What is this?

    ( char * ) &( ( struct aStruct * ) 0 )

    It looks like it's taking the address of something that contains a
    pointer to null, and casting it to a pointer to char.

    (Actually, technically, the address of a pointer to the beginning of a
    struct aStruct, that starts at address 0).

    Or, is it taking the pointer to null itself, and casting that to a
    pointer to char?

  • maverik

    #2
    Re: What is this?

    On Nov 19, 1:48 pm, Eric <answer.to.news gr...@nospam.co mwrote:
    What is this?
    >
    ( char * )  &( ( struct aStruct * )  0 )
    It wouldn't work, because you can't take address (&) of the constant
    (( struct aStruct * ) 0 ).

    Comment

    • James Kuyper

      #3
      Re: What is this?

      Eric wrote:
      >
      What is this?
      >
      ( char * ) &( ( struct aStruct * ) 0 )
      >
      It looks like it's taking the address of something that contains a
      pointer to null, and casting it to a pointer to char.
      No, it looks like something that attempts to take the address of a null
      pointer value. As such, it's a constraint violation (6.5.3.2p1).

      Comment

      • Richard Tobin

        #4
        Re: What is this?

        In article <khr7i45rsqs56s tqji4fgs9ft5fre 4oh0p@4ax.com>,
        Eric <answer.to.news group@nospam.co mwrote:
        >What is this?
        >
        >( char * ) &( ( struct aStruct * ) 0 )
        As it is, it's an error. If it were

        ( char * ) &( ( struct aStruct * ) 0 )->x

        (assuming x is a member of the struct), then it would be an
        almost-plausible (though theoretically non-portable) imitation of
        offsetof().

        -- Richard
        --
        Please remember to mention me / in tapes you leave behind.

        Comment

        • Ben Bacarisse

          #5
          Re: What is this?

          Eric <answer.to.news group@nospam.co mwrites:
          What is this?
          >
          ( char * ) &( ( struct aStruct * ) 0 )
          It is a constraint violation. That means that a conforming compiler
          must issue a diagnostic. The result of a cast is not an lvalue and
          the operand of & must be an lvalue.
          It looks like it's taking the address of something that contains a
          pointer to null, and casting it to a pointer to char.
          >
          (Actually, technically, the address of a pointer to the beginning of a
          struct aStruct, that starts at address 0).
          Not really. Once you have a constraint violation the program is
          essentially meaningless, but if we put that to one side (i.e. we
          pretend that the stated constraint is missing from the C
          specification) then all we have is an attempt to take the address of a
          null pointer constant. Null pointers (constant or otherwise) do not
          point at anything -- specifically they don't point to an object at
          "address zero".

          The context of the code might explain the mystery, but it is hard to
          guess any intent (at least I can't). Maybe there is a typo?

          --
          Ben.

          Comment

          • blargg

            #6
            Re: What is this?

            Ben Bacarisse wrote:
            Eric writes:
            What is this?

            ( char * ) &( ( struct aStruct * ) 0 )
            >
            It is a constraint violation. That means that a conforming compiler
            must issue a diagnostic. The result of a cast is not an lvalue and
            the operand of & must be an lvalue.
            >
            It looks like it's taking the address of something that contains a
            pointer to null, and casting it to a pointer to char.

            (Actually, technically, the address of a pointer to the beginning of a
            struct aStruct, that starts at address 0).
            >
            Not really. Once you have a constraint violation the program is
            essentially meaningless, but if we put that to one side (i.e. we
            pretend that the stated constraint is missing from the C
            specification) then all we have is an attempt to take the address of a
            null pointer constant. Null pointers (constant or otherwise) do not
            point at anything -- specifically they don't point to an object at
            "address zero".
            The contents of the pointer are irrelevant since we're taking its ADDRESS.
            Taking the address of a null pointer is perfectly fine (and casting this
            to char* is too):

            struct aStruct* p = NULL;
            char* cp = (char*) &p; // perfectly valid

            Maybe you were thinking of taking the address of the pointed-to object,
            that is, dereferencing it first? In C89, it's undefined behavior, but in
            C99 it's well-defined; the footnote for section 6.5.3.2 starts out: "83)
            Thus, &*E is equivalent to E (even if E is a null pointer) [...]".

            struct aStruct* p = NULL;
            char* cp = (char*) &*p; // undefined behavior in C89 (valid in C99)

            Comment

            • Ben Bacarisse

              #7
              Re: What is this?

              blargg.h4g@gish puppy.com (blargg) writes:
              Ben Bacarisse wrote:
              >Eric writes:
              What is this?
              >
              ( char * ) &( ( struct aStruct * ) 0 )
              >>
              >It is a constraint violation. That means that a conforming compiler
              >must issue a diagnostic. The result of a cast is not an lvalue and
              >the operand of & must be an lvalue.
              >>
              It looks like it's taking the address of something that contains a
              pointer to null, and casting it to a pointer to char.
              >
              (Actually, technically, the address of a pointer to the beginning of a
              struct aStruct, that starts at address 0).
              >>
              >Not really. Once you have a constraint violation the program is
              >essentially meaningless, but if we put that to one side (i.e. we
              >pretend that the stated constraint is missing from the C
              >specificatio n) then all we have is an attempt to take the address of a
              >null pointer constant. Null pointers (constant or otherwise) do not
              >point at anything -- specifically they don't point to an object at
              >"address zero".
              >
              The contents of the pointer are irrelevant since we're taking its ADDRESS.
              Taking the address of a null pointer is perfectly fine (and casting this
              to char* is too):
              Yes, true, but I don't think I contradicted that, did I? I was keen
              to correct the idea that (T *)0 is pointer to a T "at address zero".

              <snip>

              --
              Ben.

              Comment

              • jameskuyper

                #8
                Re: What is this?

                Ben Bacarisse wrote:
                Eric <answer.to.news group@nospam.co mwrites:
                >
                What is this?

                ( char * ) &( ( struct aStruct * ) 0 )
                >
                It is a constraint violation. That means that a conforming compiler
                must issue a diagnostic. The result of a cast is not an lvalue and
                the operand of & must be an lvalue.
                >
                It looks like it's taking the address of something that contains a
                pointer to null, and casting it to a pointer to char.

                (Actually, technically, the address of a pointer to the beginning of a
                struct aStruct, that starts at address 0).
                >
                Not really. Once you have a constraint violation the program is
                essentially meaningless, but if we put that to one side (i.e. we
                pretend that the stated constraint is missing from the C
                specification) then all we have is an attempt to take the address of a
                null pointer constant. Null pointers (constant or otherwise) do not
                point at anything -- specifically they don't point to an object at
                "address zero".
                The fact that this pointer is null is irrelevant. There would be no
                problem if it were a null pointer object rather than a null pointer
                constant. The problem is that it's a pointer value, not a pointer
                object, and it is just as much of a problem whether or not the pointer
                value is null.
                The context of the code might explain the mystery, but it is hard to
                guess any intent (at least I can't). Maybe there is a typo?
                If it were followed by ->x, where "x" is one of the members of struct
                aStruct, the only problem with this code would be the fact that it
                attempts to de-reference a null pointer, rendering the behavior
                undefined. For that reason, such a construct should never occur in
                user code. However, on many implementations the actual behavior of
                this construct is such that, when the result is converted to size_t,
                it constitutes a conforming implementation of the offsetof() macro.
                Since <stddef.his part of the implementation, it's perfectly
                legitimate for the implementor to take advantage of that fact inside
                of stddef.h, even though developers should not do so in user code.

                Comment

                • blargg

                  #9
                  Re: What is this?

                  Ben Bacarisse wrote:
                  blargg writes:
                  Ben Bacarisse wrote:
                  [...]
                  Null pointers (constant or otherwise) do not
                  point at anything -- specifically they don't point to an object at
                  "address zero".
                  The contents of the pointer are irrelevant since we're taking its ADDRESS.
                  Taking the address of a null pointer is perfectly fine (and casting this
                  to char* is too):
                  >
                  Yes, true, but I don't think I contradicted that, did I? I was keen
                  to correct the idea that (T *)0 is pointer to a T "at address zero".
                  Ahhh, I see now what you were getting at, that for example the
                  (non-portable) offsetof implementation based on it depends on a null
                  pointer's representation being all-zero,

                  #define offsetof(n,m) ((size_t) &((n*) 0)->m)

                  whereas something like

                  #define offsetof(n,m) ((size_t) &((n*) sizeof (n))->m - sizeof (n))

                  doesn't depend on a null pointer representation (but is still not fully
                  portable of course). Or more simply, to get a pointer to a T at zero, you
                  need something like (again, not fully portable, but then again, needing an
                  object at zero is inherently platform-specific)

                  T* t_at_zero = ((T*) sizeof (T)) - 1;

                  Comment

                  • Ben Bacarisse

                    #10
                    Re: What is this?

                    jameskuyper <jameskuyper@ve rizon.netwrites :
                    Ben Bacarisse wrote:
                    >Eric <answer.to.news group@nospam.co mwrites:
                    >>
                    What is this?
                    >
                    ( char * ) &( ( struct aStruct * ) 0 )
                    >>
                    >It is a constraint violation. That means that a conforming compiler
                    >must issue a diagnostic. The result of a cast is not an lvalue and
                    >the operand of & must be an lvalue.
                    >>
                    It looks like it's taking the address of something that contains a
                    pointer to null, and casting it to a pointer to char.
                    >
                    (Actually, technically, the address of a pointer to the beginning of a
                    struct aStruct, that starts at address 0).
                    >>
                    >Not really. Once you have a constraint violation the program is
                    >essentially meaningless, but if we put that to one side (i.e. we
                    >pretend that the stated constraint is missing from the C
                    >specificatio n) then all we have is an attempt to take the address of a
                    >null pointer constant. Null pointers (constant or otherwise) do not
                    >point at anything -- specifically they don't point to an object at
                    >"address zero".
                    >
                    The fact that this pointer is null is irrelevant. There would be no
                    problem if it were a null pointer object rather than a null pointer
                    constant. The problem is that it's a pointer value, not a pointer
                    object, and it is just as much of a problem whether or not the pointer
                    value is null.
                    Total failure to communicate on my part, I guess, since two people
                    have now made this point! I only wanted to address the phrase "a
                    struct aStruct at address 0". The cast expression (struct aStruct *)0
                    is (as you know) just a null pointer of struct aStruct * type and has
                    nothing to do with an object of type struct aStruct (and I did point
                    out what the problem really is with the code right up front!).

                    --
                    Ben.

                    Comment

                    • Ben Bacarisse

                      #11
                      Re: What is this?

                      blargg.h4g@gish puppy.com (blargg) writes:
                      Ben Bacarisse wrote:
                      >blargg writes:
                      Ben Bacarisse wrote:
                      [...]
                      >Null pointers (constant or otherwise) do not
                      >point at anything -- specifically they don't point to an object at
                      >"address zero".
                      >
                      The contents of the pointer are irrelevant since we're taking its ADDRESS.
                      Taking the address of a null pointer is perfectly fine (and casting this
                      to char* is too):
                      >>
                      >Yes, true, but I don't think I contradicted that, did I? I was keen
                      >to correct the idea that (T *)0 is pointer to a T "at address zero".
                      >
                      Ahhh, I see now what you were getting at, that for example the
                      (non-portable) offsetof implementation based on it depends on a null
                      pointer's representation being all-zero,
                      >
                      #define offsetof(n,m) ((size_t) &((n*) 0)->m)
                      No, that was not what I meant. For one thing, that code does not
                      depend on the representation of a null pointer (it is non-portable
                      because it involves de-referencing a null pointer). Honestly, all I
                      wanted to say was "null pointers do not point at anything --
                      specifically they don't point to an object at address zero".

                      I won't comment on the rest for fear of complicating matters more.

                      --
                      Ben.

                      Comment

                      • Eric

                        #12
                        Re: What is this?

                        On Wed, 19 Nov 2008 12:07:07 +0000, Ben Bacarisse
                        <ben.usenet@bsb .me.ukwrote:
                        >The context of the code might explain the mystery, but it is hard to
                        >guess any intent (at least I can't). Maybe there is a typo?
                        Good afternoon, Ben.

                        I apologize for not providing enough information... I was just trying
                        to minimize my post but I guess I minimized it too much. :-)

                        A more detailed block of code is:

                        bool result;
                        bool GetByte( char *theAddr, int theCount, char *theDest);

                        char Dest[ SOME_SIZE ];

                        result =
                        GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
                        1, ( char * ) ( &Dest ) );

                        My question is... does the struct aStruct live at address 0, or does
                        address 0 contain a pointer to wherever aStruct actually lives? Seems
                        to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
                        indicate the latter...

                        Comment

                        • Eric

                          #13
                          Re: What is this?


                          On Wed, 19 Nov 2008 22:56:14 +0000, Ben Bacarisse
                          <ben.usenet@bsb .me.ukwrote:
                          >that code does not
                          >depend on the representation of a null pointer (it is non-portable
                          >because it involves de-referencing a null pointer).
                          Technically, it's dereferencing a zero pointer, which isn't guaranteed
                          to be the same thing as a null pointer, right?

                          This code runs on a low-end microcontroller and I think the idea is
                          that they have something specific at address zero, that they want to
                          access.

                          Not really sure about that, though (yet).

                          See my other post today that shows a more complete block of code that
                          hopefully does a slightly better job of showing what they are trying
                          to do.

                          Comment

                          • jameskuyper

                            #14
                            Re: What is this?

                            Eric wrote:
                            On Wed, 19 Nov 2008 22:56:14 +0000, Ben Bacarisse
                            <ben.usenet@bsb .me.ukwrote:
                            >
                            that code does not
                            depend on the representation of a null pointer (it is non-portable
                            because it involves de-referencing a null pointer).
                            >
                            Technically, it's dereferencing a zero pointer, which isn't guaranteed
                            to be the same thing as a null pointer, right?
                            (struct aStruct*)0 is a null pointer.

                            Comment

                            • jameskuyper

                              #15
                              Re: What is this?

                              Eric wrote:
                              On Wed, 19 Nov 2008 12:07:07 +0000, Ben Bacarisse
                              <ben.usenet@bsb .me.ukwrote:
                              >
                              The context of the code might explain the mystery, but it is hard to
                              guess any intent (at least I can't). Maybe there is a typo?
                              >
                              Good afternoon, Ben.
                              >
                              I apologize for not providing enough information... I was just trying
                              to minimize my post but I guess I minimized it too much. :-)
                              That's easy to do; it's still too minimal.
                              A more detailed block of code is:
                              >
                              bool result;
                              bool GetByte( char *theAddr, int theCount, char *theDest);
                              >
                              char Dest[ SOME_SIZE ];
                              >
                              result =
                              GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
                              1, ( char * ) ( &Dest ) );
                              >
                              My question is... does the struct aStruct live at address 0, or does
                              address 0 contain a pointer to wherever aStruct actually lives? Seems
                              to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
                              indicate the latter...
                              struct aStruct is not a particular struct that resides at a particular
                              location, it is a struct type. This code creates a null pointer of
                              type "struct aStruct*", and then dereferences it. The behavior is
                              undefined, which ends the discussion as far as the C standard is
                              concerned.

                              Pragmatically, on many implementations a null pointer points at an
                              actual memory location, one that strictly conforming C code cannot
                              access. The result of the above conversion is to treat that memory
                              location as if it was the start of an object of type "struct aStruct".
                              The rest of the expression creates a char* pointer that points at the
                              location at which the "Addr" member of such a struct would reside. We
                              don't know what GetByte() will do with that pointer - you haven't told
                              us what GetByte() does. I would guess that this call to GetBytes()
                              copies 1 byte from that location into Dest.

                              This is all highly non-portable.

                              Comment

                              Working...