Assigning a pointer to an array

Discussion in 'C Programming' started by The Hole Pounder, Sep 11, 2010.

  1. My C skills are rather meager so forgive me if I do not express my
    question
    clearly enough. Here is a struct that is declared in Windows:

    typedef struct _REPARSE_GUID_DATA_BUFFER
    {
    DWORD ReparseTag;
    WORD ReparseDataLength;
    WORD Reserved;
    GUID ReparseGuid;
    struct {BYTE DataBuffer[1]; } GenericReparseBuffer;

    } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

    Now I'm going to show my attempt at assigning to "DataBuffer". This code
    is
    written in Eiffel but the part inside of the square brackets ([]) is C
    code
    except you will see some "$" symbols which you can ignore:

    set_c_generic_reparse_buffer_data_buffer_pointer (a_item, v: POINTER) is
    external
    "C inline use <Windows.h>"
    alias
    "[
    {
    PREPARSE_GUID_DATA_BUFFER itm;
    BYTE* db;
    itm = $a_item;
    db = $v;
    &((itm->GenericReparseBuffer).DataBuffer) = db;
    }
    ]"
    end

    Line 5 of the C code part is where I attempt to assign the array
    "DataBuffer[]" in the struct "GenericReparseBuffer" which is a member of
    the
    struct "REPARSE_GUID_DATA_BUFFER". My Eiffel compiler translates the
    Eiffel
    code into C and uses MSVC++ to compile it. The C compiler gives me this
    error:

    error C2106: '=' : left operand must be l-value

    I'm hoping I can get some assistance with this. Sorry about the Eiffel
    code
    but this is a problem with the C part.

    --
    ** I POUND HOLES **
    The Hole Pounder, Sep 11, 2010
    #1
    1. Advertising

  2. The Hole Pounder <> writes:

    > My C skills are rather meager so forgive me if I do not express my
    > question
    > clearly enough. Here is a struct that is declared in Windows:
    >
    > typedef struct _REPARSE_GUID_DATA_BUFFER
    > {
    > DWORD ReparseTag;
    > WORD ReparseDataLength;
    > WORD Reserved;
    > GUID ReparseGuid;
    > struct {BYTE DataBuffer[1]; } GenericReparseBuffer;


    This is significant. The 1 byte array suggests that in reality objects
    of this type will really be larger that you see here. It's a common
    technique that goes by the name "the struct hack". It means these sort
    of objects are intended to be over-allocated with the extra space being
    available via the array member called DataBuffer.

    > } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;
    >
    > Now I'm going to show my attempt at assigning to "DataBuffer". This code
    > is
    > written in Eiffel but the part inside of the square brackets ([]) is C
    > code
    > except you will see some "$" symbols which you can ignore:
    >
    > set_c_generic_reparse_buffer_data_buffer_pointer (a_item, v: POINTER) is
    > external
    > "C inline use <Windows.h>"
    > alias
    > "[
    > {
    > PREPARSE_GUID_DATA_BUFFER itm;
    > BYTE* db;
    > itm = $a_item;
    > db = $v;


    You say this is C but these two lines (with the $s) are not C. To help
    in detail, people would need to know what these lines mean and that to
    do with the Eiffel/C interface.

    > &((itm->GenericReparseBuffer).DataBuffer) = db;


    You don't need any of those parentheses though of course they do no
    harm.

    > }
    > ]"
    > end
    >
    > Line 5 of the C code part is where I attempt to assign the array
    > "DataBuffer[]" in the struct "GenericReparseBuffer" which is a member of
    > the
    > struct "REPARSE_GUID_DATA_BUFFER". My Eiffel compiler translates the
    > Eiffel
    > code into C and uses MSVC++ to compile it. The C compiler gives me this
    > error:
    >
    > error C2106: '=' : left operand must be l-value


    The compiler is telling you can't assign to the result of an
    &expression. Just like +x = 1 is not allowed, neither is &<anything> =
    <anything else>.

    & gives you the address and I can see why you want to assign to it --
    your intent is probably to make DataBuffer point at the data you want it
    to but you simply can't do that. Had the structure defined that member
    to be a pointer you could (and you would not need the &) but an array
    can't be made to refer to anything other than it elements.

    It's not possible for me to help much more because I have no idea what
    this fragment of code is supposed to do. Should it allocate a
    REPARSE_GUID_DATA_BUFFER? Should it copy the data pointed to by 'v'
    into the DataBuffer member of an existing REPARSE_GUID_DATA_BUFFER?
    How much data should be copied?

    > I'm hoping I can get some assistance with this. Sorry about the Eiffel
    > code
    > but this is a problem with the C part.


    It's mainly an Eiffel issue in the sense that Eiffel people can tell you
    how this sort of thing is usually done. For a C person to help, you'd
    have to provide a lot of detail about exactly what the code should do.
    If you can find some Eiffel group, that is likely to be a better source
    of help.

    --
    Ben.
    Ben Bacarisse, Sep 11, 2010
    #2
    1. Advertising

  3. On 11 Sep, 22:07, The Hole Pounder <> wrote:
    >             &((itm->GenericReparseBuffer).DataBuffer) = db;
    > error C2106: '=' : left operand must be l-value

    The issue here is that the & operator returns the address of that
    struct member, you can not assign to that the compiler decides where
    it goes. It looks like you are expecting DataBuffer to be a pointer in
    which case this would work without the &, however...

    >     struct {BYTE DataBuffer[1]; } GenericReparseBuffer;

    I have to say I find this definition a bit suspect this defines
    DataBuffer as an array rather than a pointer. Whilst for the most part
    they are fairly interchangeable in C, in this case space will actually
    be allocated in the struct for the bytes, in this case just 1 byte.
    Effectively, this means you can't assign the address of something to
    it and just have to use the provided 1 byte buffer. Perhaps someone
    who knows the Windows API better than me can shed some light on the
    appropriate use of this struct.

    Hope that helps some,
    Charles Keepax
    Charles Keepax, Sep 11, 2010
    #3
  4. Charles Keepax <> writes:
    <snip>
    >>     struct {BYTE DataBuffer[1]; } GenericReparseBuffer;

    > I have to say I find this definition a bit suspect this defines
    > DataBuffer as an array rather than a pointer. Whilst for the most part
    > they are fairly interchangeable in C, in this case space will actually
    > be allocated in the struct for the bytes, in this case just 1 byte.
    > Effectively, this means you can't assign the address of something to
    > it and just have to use the provided 1 byte buffer. Perhaps someone
    > who knows the Windows API better than me can shed some light on the
    > appropriate use of this struct.


    It is almost certainly an example of the struct hack described here:

    http://c-faq.com/struct/structhack.html

    --
    Ben.
    Ben Bacarisse, Sep 11, 2010
    #4
  5. The Hole Pounder

    Nick Guest

    The Hole Pounder <> writes:

    > My C skills are rather meager so forgive me if I do not express my
    > question
    > clearly enough. Here is a struct that is declared in Windows:
    >
    > typedef struct _REPARSE_GUID_DATA_BUFFER
    > {
    > DWORD ReparseTag;
    > WORD ReparseDataLength;
    > WORD Reserved;
    > GUID ReparseGuid;
    > struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >
    > } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;


    I've never liked typedefing a pointer rather than defining the bare type
    and using a * when you want a pointer (just like stdio.h does with FILE
    - that's a big hint to everybody), and I've never liked Hungarian style
    notation.

    Here we see the two coming together in an horrible way. You appear to
    have two buffer types, one for reparsing and one for preparsing, but
    in fact:
    REPARSE_GUID_DATA_BUFFER *ptr
    will generate a PREPARSE_GUID_DATA_BUFFER.

    Urg!
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
    Nick, Sep 12, 2010
    #5
  6. Nick <> writes:

    > The Hole Pounder <> writes:
    >
    >> My C skills are rather meager so forgive me if I do not express my
    >> question
    >> clearly enough. Here is a struct that is declared in Windows:
    >>
    >> typedef struct _REPARSE_GUID_DATA_BUFFER
    >> {
    >> DWORD ReparseTag;
    >> WORD ReparseDataLength;
    >> WORD Reserved;
    >> GUID ReparseGuid;
    >> struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >>
    >> } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

    >
    > I've never liked typedefing a pointer rather than defining the bare type
    > and using a * when you want a pointer (just like stdio.h does with FILE
    > - that's a big hint to everybody), and I've never liked Hungarian style
    > notation.


    I don't see anything that I'd call Hungarian there.

    <snip>
    --
    Ben.
    Ben Bacarisse, Sep 12, 2010
    #6
  7. The Hole Pounder

    Shao Miller Guest

    Nick wrote:
    > The Hole Pounder <> writes:
    >> ... ... ... Here is a struct that is declared in Windows:
    >>
    >> typedef struct _REPARSE_GUID_DATA_BUFFER
    >> {
    >> DWORD ReparseTag;
    >> WORD ReparseDataLength;
    >> WORD Reserved;
    >> GUID ReparseGuid;
    >> struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >>
    >> } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

    >
    > I've never liked typedefing a pointer rather than defining the bare type
    > and using a * when you want a pointer (just like stdio.h does with FILE
    > - that's a big hint to everybody), and I've never liked Hungarian style
    > notation.
    >
    > Here we see the two coming together in an horrible way. You appear to
    > have two buffer types, one for reparsing and one for preparsing, but
    > in fact:
    > REPARSE_GUID_DATA_BUFFER *ptr
    > will generate a PREPARSE_GUID_DATA_BUFFER.
    >
    > Urg!


    That's just the way it is, in Windows. That is, it's pretty common.
    The above is from Microsoft.
    Shao Miller, Sep 12, 2010
    #7
  8. The Hole Pounder

    BartC Guest

    "Ben Bacarisse" <> wrote in message
    news:...
    > Nick <> writes:


    >>> typedef struct _REPARSE_GUID_DATA_BUFFER
    >>> {
    >>> DWORD ReparseTag;
    >>> WORD ReparseDataLength;
    >>> WORD Reserved;
    >>> GUID ReparseGuid;
    >>> struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >>>
    >>> } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

    >>
    >> I've never liked typedefing a pointer rather than defining the bare type
    >> and using a * when you want a pointer (just like stdio.h does with FILE
    >> - that's a big hint to everybody), and I've never liked Hungarian style
    >> notation.

    >
    > I don't see anything that I'd call Hungarian there.


    Possibly the "P" in "PREPARSE" (pointer to a REPARSE buffer). This is
    confusing because it looks like "PRE-PARSE".

    --
    Bartc
    BartC, Sep 13, 2010
    #8
  9. "BartC" <> writes:

    > "Ben Bacarisse" <> wrote in message
    > news:...
    >> Nick <> writes:

    >
    >>>> typedef struct _REPARSE_GUID_DATA_BUFFER
    >>>> {
    >>>> DWORD ReparseTag;
    >>>> WORD ReparseDataLength;
    >>>> WORD Reserved;
    >>>> GUID ReparseGuid;
    >>>> struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >>>>
    >>>> } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;
    >>>
    >>> I've never liked typedefing a pointer rather than defining the bare type
    >>> and using a * when you want a pointer (just like stdio.h does with FILE
    >>> - that's a big hint to everybody), and I've never liked Hungarian style
    >>> notation.

    >>
    >> I don't see anything that I'd call Hungarian there.

    >
    > Possibly the "P" in "PREPARSE" (pointer to a REPARSE buffer). This is
    > confusing because it looks like "PRE-PARSE".


    I see, yes, that might count. Hungarian prefixes are normally lower
    case though.

    --
    Ben.
    Ben Bacarisse, Sep 13, 2010
    #9
  10. The Hole Pounder

    Nick Guest

    Shao Miller <> writes:

    > Nick wrote:
    >> The Hole Pounder <> writes:
    >>> ... ... ... Here is a struct that is declared in Windows:
    >>>
    >>> typedef struct _REPARSE_GUID_DATA_BUFFER
    >>> {
    >>> DWORD ReparseTag;
    >>> WORD ReparseDataLength;
    >>> WORD Reserved;
    >>> GUID ReparseGuid;
    >>> struct {BYTE DataBuffer[1]; } GenericReparseBuffer;
    >>>
    >>> } REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;

    >>
    >> I've never liked typedefing a pointer rather than defining the bare type
    >> and using a * when you want a pointer (just like stdio.h does with FILE
    >> - that's a big hint to everybody), and I've never liked Hungarian style
    >> notation.
    >>
    >> Here we see the two coming together in an horrible way. You appear to
    >> have two buffer types, one for reparsing and one for preparsing, but
    >> in fact:
    >> REPARSE_GUID_DATA_BUFFER *ptr
    >> will generate a PREPARSE_GUID_DATA_BUFFER.
    >>
    >> Urg!

    >
    > That's just the way it is, in Windows. That is, it's pretty
    > common. The above is from Microsoft.


    Finally the explanation for all those botnets is starting to appear.
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
    Nick, Sep 13, 2010
    #10
  11. The Hole Pounder

    Shao Miller Guest

    Nick wrote:
    > Shao Miller <> writes:
    >> That's just the way it is, in Windows. That is, it's pretty
    >> common. The above is from Microsoft.

    >
    > Finally the explanation for all those botnets is starting to appear.


    Har har har! Very funny!
    Shao Miller, Sep 13, 2010
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Saunders

    Assigning a pointer to an array

    Chris Saunders, Jun 7, 2008, in forum: C Programming
    Replies:
    2
    Views:
    337
    Chris Saunders
    Jun 9, 2008
  2. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    439
    James Kuyper
    Sep 23, 2011
  3. Richard Lionheart
    Replies:
    27
    Views:
    378
    Jean-Hugues ROBERT
    May 4, 2004
  4. weston
    Replies:
    1
    Views:
    238
    Richard Cornford
    Sep 22, 2006
  5. bintom
    Replies:
    11
    Views:
    637
    Luca Risolia
    Oct 15, 2012
Loading...

Share This Page