Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #75135 > unrolled thread

Help with a known member reference in forward conveyance

Started by"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
First post2015-11-06 09:27 -0800
Last post2015-11-10 12:20 -0500
Articles 20 on this page of 21 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Help with a known member reference in forward conveyance "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-06 09:27 -0800
    Re: Help with a known member reference in forward conveyance Barry Schwarz <schwarzb@dqel.com> - 2015-11-06 11:06 -0800
    Re: Help with a known member reference in forward conveyance Bartc <bc@freeuk.com> - 2015-11-06 19:20 +0000
    Re: Help with a known member reference in forward conveyance Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-06 20:21 +0000
      Re: Help with a known member reference in forward conveyance "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-06 13:27 -0800
    Re: Help with a known member reference in forward conveyance Philip Lantz <prl@canterey.us> - 2015-11-07 01:37 -0800
      Re: Help with a known member reference in forward conveyance Bartc <bc@freeuk.com> - 2015-11-07 10:45 +0000
        Re: Help with a known member reference in forward conveyance "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-07 05:06 -0800
        Re: Help with a known member reference in forward conveyance Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-07 17:26 +0000
        Re: Help with a known member reference in forward conveyance Philip Lantz <prl@canterey.us> - 2015-11-07 11:20 -0800
        Re: Help with a known member reference in forward conveyance Philip Lantz <prl@canterey.us> - 2015-11-07 11:22 -0800
      Re: Help with a known member reference in forward conveyance "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-07 05:05 -0800
        Re: Help with a known member reference in forward conveyance Philip Lantz <prl@canterey.us> - 2015-11-07 11:35 -0800
          Re: Help with a known member reference in forward conveyance "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-11-07 12:06 -0800
          Re: Help with a known member reference in forward conveyance Ian Collins <ian-news@hotmail.com> - 2015-11-08 09:17 +1300
            Re: Help with a known member reference in forward conveyance Philip Lantz <prl@canterey.us> - 2015-11-07 13:51 -0800
              Re: Help with a known member reference in forward conveyance Ian Collins <ian-news@hotmail.com> - 2015-11-08 11:18 +1300
                Re: Help with a known member reference in forward conveyance raltbos@xs4all.nl (Richard Bos) - 2015-11-10 16:58 +0000
                  Re: Help with a known member reference in forward conveyance Keith Thompson <kst-u@mib.org> - 2015-11-10 09:15 -0800
                    Re: Help with a known member reference in forward conveyance raltbos@xs4all.nl (Richard Bos) - 2015-11-10 19:05 +0000
                  Re: Help with a known member reference in forward conveyance James Kuyper <jameskuyper@verizon.net> - 2015-11-10 12:20 -0500

Page 1 of 2  [1] 2  Next page →


#75135 — Help with a known member reference in forward conveyance

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2015-11-06 09:27 -0800
SubjectHelp with a known member reference in forward conveyance
Message-ID<b2458ed7-1f02-4177-89b0-df952b1f2163@googlegroups.com>
I have a situation in C code where I know the member I need to update
in a pointer to a struct, but I don't yet have the pointer allocated
that I need to update, so I can't obtain its exact address yet.

Example:

    01:    extern struct SData;
    02:  
    03:    struct SContainer
    04:    {
    05:        struct SData*   d1;
    06:        struct SData*   d2;
    07:        struct SData*   d3;
    08:        struct SData*   d4;
    09:        struct SData*   d5;
    10:        struct SData*   d6;
    11:        struct SData*   d7;
    12:        struct SData*   d8;
    13:    };
    14:  
    15:    if (some_test)
    16:        // I know here that I need to update d5
    17:  
    18:    // More instructions
    19:  
    20:    // Allocate pointer
    21:    struct SContainer* c = malloc(sizeof(struct SContainer));
    22:    if (c)
    23:    {
    24:        // Now I need to update c->d5, but how ??
    25:    }

On 15: and 16:, I'm able to determine through logic that the member
I need to update is d5, for example, within the struct SContainer
structure.  I know that, but it will be many instructions later
before I am able to allocate the pointer which actually needs that
structure, thereby making the address of d5 known within.  And it
may even be in a called function where the ultimate update takes
place.

Is there any way to convey that information in a way that doesn't
involve a switch () { } statement, or determining the member offset,
casting my future-allocated pointer to char*, adding in that offset,
then re-casting back to its final form?

I'm looking for something like this "memberRef" ability, which conveys
the relative offset for the struct without manual mechanics:

    14:    struct SContainer? t;   // A member reference holder
    15:
    16:    if (some_test)
    17:        t = d5;             // Need to update d5
    18:  
    19:    // More instructions
    20:  
    21:    // Allocate pointer
    22:    struct SContainer* c = malloc(sizeof(struct SContainer));
    23:    if (c)
    24:    {
    25:        // Now I can update c->d5 without knowing what it was
    26:        // in 16: directly, but I simply use the t ?memberRef.
    26:        c->?t = ptr;
    27:        // At this point, c->d5 was set to ptr
    28:    }

The compiler would automatically convey some runtime checking on the
type to make sure I'm populating into something that's compatible.

Is there any ability to do this dynamically in C (or C++)?

Best regards,
Rick C. Hodgin

[toc] | [next] | [standalone]


#75155

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-11-06 11:06 -0800
Message-ID<7srp3b17e432evnubatvb6r4bhte4j9vhv@4ax.com>
In reply to#75135
On Fri, 6 Nov 2015 09:27:52 -0800 (PST), "Rick C. Hodgin"
<rick.c.hodgin@gmail.com> wrote:

As you say, until you allocate the structure you cannot do anything
with c->d5.  But you can play with t.  For example, use memset to set
each byte to 0xff.  At line 16, update whatever member(s) in t you
decide.  At line 24:
     loop through both t and *c with unsigned char pointers for
sizeof(struct SContainer) iterations
     when you find a value in t that is not 0xff, it will be the start
of some updated member (such as d5) that was updated at line 16
          use memcpy to copy sizeof(struct SData) bytes from the
pointer to t address to the pointer to *c address
          increment both pointers and iteration count by sizeof(struct
SData)-1
     increment both pointers and iteration count by 1 and repeat loop

No switches and no offsets.  

But the process would be much simpler if you did not prohibit offsets
and it would involve only a single cast to char*:
     before line 16 define struct SData *dx and size_t c_offset
     at line 16, save the value in dx and the member offset in
c_offset
     at line 24, use memcpy((char*)c+c_offset, &dx, sizeof dx) to
store the saved value in the proper member

This also eliminates the need for t.
     
>I have a situation in C code where I know the member I need to update
>in a pointer to a struct, but I don't yet have the pointer allocated
>that I need to update, so I can't obtain its exact address yet.
>
>Example:
>
>    01:    extern struct SData;
>    02:  
>    03:    struct SContainer
>    04:    {
>    05:        struct SData*   d1;
>    06:        struct SData*   d2;
>    07:        struct SData*   d3;
>    08:        struct SData*   d4;
>    09:        struct SData*   d5;
>    10:        struct SData*   d6;
>    11:        struct SData*   d7;
>    12:        struct SData*   d8;
>    13:    };
>    14:  
>    15:    if (some_test)
>    16:        // I know here that I need to update d5
>    17:  
>    18:    // More instructions
>    19:  
>    20:    // Allocate pointer
>    21:    struct SContainer* c = malloc(sizeof(struct SContainer));
>    22:    if (c)
>    23:    {
>    24:        // Now I need to update c->d5, but how ??
>    25:    }
>
>On 15: and 16:, I'm able to determine through logic that the member
>I need to update is d5, for example, within the struct SContainer
>structure.  I know that, but it will be many instructions later
>before I am able to allocate the pointer which actually needs that
>structure, thereby making the address of d5 known within.  And it
>may even be in a called function where the ultimate update takes
>place.
>
>Is there any way to convey that information in a way that doesn't
>involve a switch () { } statement, or determining the member offset,
>casting my future-allocated pointer to char*, adding in that offset,
>then re-casting back to its final form?
>
>I'm looking for something like this "memberRef" ability, which conveys
>the relative offset for the struct without manual mechanics:
>
>    14:    struct SContainer? t;   // A member reference holder
>    15:
>    16:    if (some_test)
>    17:        t = d5;             // Need to update d5
>    18:  
>    19:    // More instructions
>    20:  
>    21:    // Allocate pointer
>    22:    struct SContainer* c = malloc(sizeof(struct SContainer));
>    23:    if (c)
>    24:    {
>    25:        // Now I can update c->d5 without knowing what it was
>    26:        // in 16: directly, but I simply use the t ?memberRef.
>    26:        c->?t = ptr;
>    27:        // At this point, c->d5 was set to ptr
>    28:    }
>
>The compiler would automatically convey some runtime checking on the
>type to make sure I'm populating into something that's compatible.
>
>Is there any ability to do this dynamically in C (or C++)?
>
>Best regards,
>Rick C. Hodgin

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#75161

FromBartc <bc@freeuk.com>
Date2015-11-06 19:20 +0000
Message-ID<n1iue4$fdm$1@dont-email.me>
In reply to#75135
On 06/11/2015 17:27, Rick C. Hodgin wrote:
> I have a situation in C code where I know the member I need to update
> in a pointer to a struct, but I don't yet have the pointer allocated
> that I need to update, so I can't obtain its exact address yet.
>
> Example:
>
>      01:    extern struct SData;
>      02:
>      03:    struct SContainer
>      04:    {
>      05:        struct SData*   d1;
>      06:        struct SData*   d2;
>      07:        struct SData*   d3;
>      08:        struct SData*   d4;
>      09:        struct SData*   d5;
>      10:        struct SData*   d6;
>      11:        struct SData*   d7;
>      12:        struct SData*   d8;
>      13:    };
>      14:
>      15:    if (some_test)
>      16:        // I know here that I need to update d5
>      17:
>      18:    // More instructions
>      19:
>      20:    // Allocate pointer
>      21:    struct SContainer* c = malloc(sizeof(struct SContainer));
>      22:    if (c)
>      23:    {
>      24:        // Now I need to update c->d5, but how ??
>      25:    }
>
> On 15: and 16:, I'm able to determine through logic that the member
> I need to update is d5, for example, within the struct SContainer
> structure.

Difficult, as an instance of SContainer doesn't yet exist.

  I know that, but it will be many instructions later
> before I am able to allocate the pointer which actually needs that
> structure, thereby making the address of d5 known within.

d5 won't have an address; only on offset within whatever instance of 
SContainer is of interest (*c, in your example).

Presumably you want to update c->d5 itself, rather than what c->d5 
points to?

In your example, c->d5 will contain garbage at that point, so you can't 
talk of updating it.

   And it
> may even be in a called function where the ultimate update takes
> place.
>
> Is there any way to convey that information in a way that doesn't
> involve a switch () { } statement, or determining the member offset,
> casting my future-allocated pointer to char*, adding in that offset,
> then re-casting back to its final form?

So the problem is remembering that it is d5 rather than some other 
element that needs to be 'updated'?

I think you may be looking at an array of SData* inside the struct, or a 
union between an array, and the set of pointers d1 to d8. (Although, 
being zero-based, d5 would be element 4 of the array not 5.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#75175

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-06 20:21 +0000
Message-ID<87mvuqvpzn.fsf@bsb.me.uk>
In reply to#75135
"Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes:
<snip>
>     03:    struct SContainer
>     04:    {
>     05:        struct SData*   d1;
>     06:        struct SData*   d2;
>     07:        struct SData*   d3;
>     08:        struct SData*   d4;
>     09:        struct SData*   d5;
>     10:        struct SData*   d6;
>     11:        struct SData*   d7;
>     12:        struct SData*   d8;
>     13:    };
<snip>
> I'm looking for something like this "memberRef" ability, which conveys
> the relative offset for the struct without manual mechanics:

You can do it with offsetof:
>
>     14:    struct SContainer? t;   // A member reference holder

At this point, just declare

  size_t member_offset;
  
>     15:
>     16:    if (some_test)
>     17:        t = d5;             // Need to update d5

                 member_offset = offsetof(struct SContainer, d5);
                 
>     18:  
>     19:    // More instructions
>     20:  
>     21:    // Allocate pointer
>     22:    struct SContainer* c = malloc(sizeof(struct SContainer));
>     23:    if (c)
>     24:    {
>     25:        // Now I can update c->d5 without knowing what it was
>     26:        // in 16: directly, but I simply use the t ?memberRef.
>     26:        c->?t = ptr;

                 struct SData *dp = (void *)((char *)c + member_offset);
                 *dp = ptr;

>     27:        // At this point, c->d5 was set to ptr
>     28:    }

But the form of struct SContainer suggests an array of SData pointers
would be better.  Then you just need to remember an index.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#75186

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2015-11-06 13:27 -0800
Message-ID<2eac0c87-aba2-407e-9244-0db5ce68192b@googlegroups.com>
In reply to#75175
On Friday, November 6, 2015 at 3:21:18 PM UTC-5, Ben Bacarisse wrote:
> "Rick C. Hodgin" <rick.c.hodgin@gmail.com> writes:
> <snip>
> >     03:    struct SContainer
> >     04:    {
> >     05:        struct SData*   d1;
> >     06:        struct SData*   d2;
> >     07:        struct SData*   d3;
> >     08:        struct SData*   d4;
> >     09:        struct SData*   d5;
> >     10:        struct SData*   d6;
> >     11:        struct SData*   d7;
> >     12:        struct SData*   d8;
> >     13:    };
>
> [snip]
>
> But the form of struct SContainer suggests an array of SData pointers
> would be better.  Then you just need to remember an index.

Quite correct!  I've changed the code this related to so it reflects
use of arrays based on that suggestion.  A much better solution.

-----
On the member reference front:

I've gone ahead and defined this concept for CAlive as a "conveyable
member reference," which allows this type of member reference by prior
setting to then access data through a native object or pointer using
the syntax:

    struct SContainer? t;
    t = d5;

    c->?t  = ptr;   // With type checking, mild performance hit
    c->??t = ptr;   // Without type checking, fast

The value stored for t is an offset.  It can be used to access any
member, passed as a parameter for access, and so on.  With type
checking, it incurs some overhead related the lookup to validate
the target member supports assignment from the input, or if used
to access the member, that the value in t point to a real member.

Some speed can be gained if you, the developer, know that the value
in "t" would be correct.  This would be the c->??t syntax shown above.

-----
I have considered reversing these syntaxes and using c->??t for type
checking, and c->?t for non-type checking as I expect it would be
used more often, and in some contexts, type checking would always be
required regardless of ? or ?? syntax.  We'll see.

    https://groups.google.com/forum/#!topic/caliveprogramminglanguage/FWzhrpHZIm4

Best regards,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#75237

FromPhilip Lantz <prl@canterey.us>
Date2015-11-07 01:37 -0800
Message-ID<MPG.30a76633669f6edc87@news.eternal-september.org>
In reply to#75135
Rick C. Hodgin wrote:
> 
> I have a situation in C code where I know the member I need to update
> in a pointer to a struct, but I don't yet have the pointer allocated
> that I need to update, so I can't obtain its exact address yet.
> 
> Example:
> 
>     01:    extern struct SData;
>     02:  
>     03:    struct SContainer
>     04:    {
>     05:        struct SData*   d1;
>     06:        struct SData*   d2;
>     07:        struct SData*   d3;
>     08:        struct SData*   d4;
>     09:        struct SData*   d5;
>     10:        struct SData*   d6;
>     11:        struct SData*   d7;
>     12:        struct SData*   d8;
>     13:    };
>     14:  
>     15:    if (some_test)
>     16:        // I know here that I need to update d5
>     17:  
>     18:    // More instructions
>     19:  
>     20:    // Allocate pointer
>     21:    struct SContainer* c = malloc(sizeof(struct SContainer));
>     22:    if (c)
>     23:    {
>     24:        // Now I need to update c->d5, but how ??
>     25:    }
> 
> On 15: and 16:, I'm able to determine through logic that the member
> I need to update is d5, for example, within the struct SContainer
> structure.  I know that, but it will be many instructions later
> before I am able to allocate the pointer which actually needs that
> structure, thereby making the address of d5 known within.  And it
> may even be in a called function where the ultimate update takes
> place.
> 
> Is there any way to convey that information in a way that doesn't
> involve a switch () { } statement, or determining the member offset,
> casting my future-allocated pointer to char*, adding in that offset,
> then re-casting back to its final form?
> 
> I'm looking for something like this "memberRef" ability, which conveys
> the relative offset for the struct without manual mechanics:
> 
>     14:    struct SContainer? t;   // A member reference holder
>     15:
>     16:    if (some_test)
>     17:        t = d5;             // Need to update d5
>     18:  
>     19:    // More instructions
>     20:  
>     21:    // Allocate pointer
>     22:    struct SContainer* c = malloc(sizeof(struct SContainer));
>     23:    if (c)
>     24:    {
>     25:        // Now I can update c->d5 without knowing what it was
>     26:        // in 16: directly, but I simply use the t ?memberRef.
>     26:        c->?t = ptr;
>     27:        // At this point, c->d5 was set to ptr
>     28:    }
> 
> The compiler would automatically convey some runtime checking on the
> type to make sure I'm populating into something that's compatible.
> 
> Is there any ability to do this dynamically in C (or C++)?

I'll probably get complaints for saying this here...

Your hypothetical syntax is so close to the existing C++ syntax that
I wonder if you have encountered it before and forgotten.

14:     struct SData *SContainer::*t;  // A member reference holder
15:
16:     if (some_test)
17:         t = &SContainer::d5;       // Need to update d5
...
26:         c->*t = ptr;
27:         // At this point, c->d5 was set to ptr

[toc] | [prev] | [next] | [standalone]


#75244

FromBartc <bc@freeuk.com>
Date2015-11-07 10:45 +0000
Message-ID<n1kkje$hmj$1@dont-email.me>
In reply to#75237
On 07/11/2015 09:37, Philip Lantz wrote:
> Rick C. Hodgin wrote:
>>
>> I have a situation in C code where I know the member I need to update
>> in a pointer to a struct, but I don't yet have the pointer allocated
>> that I need to update, so I can't obtain its exact address yet.
>>
>> Example:
>>
>>      01:    extern struct SData;
>>      02:
>>      03:    struct SContainer
>>      04:    {
>>      05:        struct SData*   d1;
>>      06:        struct SData*   d2;
>>      07:        struct SData*   d3;
>>      08:        struct SData*   d4;
>>      09:        struct SData*   d5;
>>      10:        struct SData*   d6;
>>      11:        struct SData*   d7;
>>      12:        struct SData*   d8;
>>      13:    };

>> Is there any ability to do this dynamically in C (or C++)?

> Your hypothetical syntax is so close to the existing C++ syntax that
> I wonder if you have encountered it before and forgotten.
>
> 14:     struct SData *SContainer::*t;  // A member reference holder

(What's the purpose of the first * here?)

> 15:
> 16:     if (some_test)
> 17:         t = &SContainer::d5;       // Need to update d5
> ...
> 26:         c->*t = ptr;
> 27:         // At this point, c->d5 was set to ptr

Not having looked into the murky corners of C++ recently, I was feeling 
quite amiable towards it. Until your example.

Is t a pointer to some imaginary object? If so then that's all we need!

-- 
Bartc



[toc] | [prev] | [next] | [standalone]


#75251

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2015-11-07 05:06 -0800
Message-ID<5815921a-0510-47db-ba32-8e0a1f62a326@googlegroups.com>
In reply to#75244
On Saturday, November 7, 2015 at 5:45:18 AM UTC-5, Bart wrote:
> On 07/11/2015 09:37, Philip Lantz wrote:
> > Rick C. Hodgin wrote:
> >>
> >> I have a situation in C code where I know the member I need to update
> >> in a pointer to a struct, but I don't yet have the pointer allocated
> >> that I need to update, so I can't obtain its exact address yet.
> >>
> >> Example:
> >>
> >>      01:    extern struct SData;
> >>      02:
> >>      03:    struct SContainer
> >>      04:    {
> >>      05:        struct SData*   d1;
> >>      06:        struct SData*   d2;
> >>      07:        struct SData*   d3;
> >>      08:        struct SData*   d4;
> >>      09:        struct SData*   d5;
> >>      10:        struct SData*   d6;
> >>      11:        struct SData*   d7;
> >>      12:        struct SData*   d8;
> >>      13:    };
> 
> >> Is there any ability to do this dynamically in C (or C++)?
> 
> > Your hypothetical syntax is so close to the existing C++ syntax that
> > I wonder if you have encountered it before and forgotten.
> >
> > 14:     struct SData *SContainer::*t;  // A member reference holder
> 
> (What's the purpose of the first * here?)

My guess is that it's used that way so the parser will know what it is.

> > 15:
> > 16:     if (some_test)
> > 17:         t = &SContainer::d5;       // Need to update d5
> > ...
> > 26:         c->*t = ptr;
> > 27:         // At this point, c->d5 was set to ptr
> 
> Not having looked into the murky corners of C++ recently, I was feeling 
> quite amiable towards it. Until your example.
> 
> Is t a pointer to some imaginary object? If so then that's all we need!
> 
> -- 
> Bartc

Best regards,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#75273

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-07 17:26 +0000
Message-ID<87a8qpu3f2.fsf@bsb.me.uk>
In reply to#75244
Bartc <bc@freeuk.com> writes:

> On 07/11/2015 09:37, Philip Lantz wrote:
>> Rick C. Hodgin wrote:
<snip>
>>>      01:    extern struct SData;
>>>      02:
>>>      03:    struct SContainer
>>>      04:    {
>>>      05:        struct SData*   d1;
>>>      06:        struct SData*   d2;
>>>      07:        struct SData*   d3;
>>>      08:        struct SData*   d4;
>>>      09:        struct SData*   d5;
>>>      10:        struct SData*   d6;
>>>      11:        struct SData*   d7;
>>>      12:        struct SData*   d8;
>>>      13:    };
>
>>> Is there any ability to do this dynamically in C (or C++)?
>
>> Your hypothetical syntax is so close to the existing C++ syntax that
>> I wonder if you have encountered it before and forgotten.
>>
>> 14:     struct SData *SContainer::*t;  // A member reference holder
>
> (What's the purpose of the first * here?)

It's part of the type of the pointer.  Reading right to left (as one
often does for C and C++ types): t is a pointer to an member of
SContainer with type pointer to struct SData.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#75284

FromPhilip Lantz <prl@canterey.us>
Date2015-11-07 11:20 -0800
Message-ID<MPG.30a7eec0d41e878a88@news.eternal-september.org>
In reply to#75244
Bartc wrote:
> 
> On 07/11/2015 09:37, Philip Lantz wrote:
> > Rick C. Hodgin wrote:
> >>
> >> I have a situation in C code where I know the member I need to update
> >> in a pointer to a struct, but I don't yet have the pointer allocated
> >> that I need to update, so I can't obtain its exact address yet.
> >>
> >> Example:
> >>
> >>      01:    extern struct SData;
> >>      02:
> >>      03:    struct SContainer
> >>      04:    {
> >>      05:        struct SData*   d1;
> >>      06:        struct SData*   d2;
> >>      07:        struct SData*   d3;
> >>      08:        struct SData*   d4;
> >>      09:        struct SData*   d5;
> >>      10:        struct SData*   d6;
> >>      11:        struct SData*   d7;
> >>      12:        struct SData*   d8;
> >>      13:    };
> 
> >> Is there any ability to do this dynamically in C (or C++)?
> 
> > Your hypothetical syntax is so close to the existing C++ syntax that
> > I wonder if you have encountered it before and forgotten.
> >
> > 14:     struct SData *SContainer::*t;  // A member reference holder
> 
> (What's the purpose of the first * here?)

SData * is the type of the member the pointer points to. 

Here's a simpler example:

struct X {
    int y;
};

int X::*t;
X x;
x.*t = 6;

[toc] | [prev] | [next] | [standalone]


#75285

FromPhilip Lantz <prl@canterey.us>
Date2015-11-07 11:22 -0800
Message-ID<MPG.30a7ef63b0cc1a7189@news.eternal-september.org>
In reply to#75244
Bartc wrote:
> Philip Lantz wrote:
> > Rick C. Hodgin wrote:
> >>
> >> I have a situation in C code where I know the member I need to update
> >> in a pointer to a struct, but I don't yet have the pointer allocated
> >> that I need to update, so I can't obtain its exact address yet.
> >>
[description of C++ pointer-to-member]
> 
> Not having looked into the murky corners of C++ recently, I was feeling 
> quite amiable towards it. Until your example.
> 
> Is t a pointer to some imaginary object? If so then that's all we need!

It's essentially a type-safe implementation of the offsetof solution in C
that Ben posted yesterday.

[toc] | [prev] | [next] | [standalone]


#75250

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2015-11-07 05:05 -0800
Message-ID<45588517-71f5-4c4a-b554-b6ca2544d7f4@googlegroups.com>
In reply to#75237
On Saturday, November 7, 2015 at 4:37:45 AM UTC-5, Philip Lantz wrote:
> Rick C. Hodgin wrote:
> > 
> > I have a situation in C code where I know the member I need to update
> > in a pointer to a struct, but I don't yet have the pointer allocated
> > that I need to update, so I can't obtain its exact address yet.
> > 
> > Example:
> > 
> >     01:    extern struct SData;
> >     02:  
> >     03:    struct SContainer
> >     04:    {
> >     05:        struct SData*   d1;
> >     06:        struct SData*   d2;
> >     07:        struct SData*   d3;
> >     08:        struct SData*   d4;
> >     09:        struct SData*   d5;
> >     10:        struct SData*   d6;
> >     11:        struct SData*   d7;
> >     12:        struct SData*   d8;
> >     13:    };
> >     14:  
> >     15:    if (some_test)
> >     16:        // I know here that I need to update d5
> >     17:  
> >     18:    // More instructions
> >     19:  
> >     20:    // Allocate pointer
> >     21:    struct SContainer* c = malloc(sizeof(struct SContainer));
> >     22:    if (c)
> >     23:    {
> >     24:        // Now I need to update c->d5, but how ??
> >     25:    }
> > 
> > On 15: and 16:, I'm able to determine through logic that the member
> > I need to update is d5, for example, within the struct SContainer
> > structure.  I know that, but it will be many instructions later
> > before I am able to allocate the pointer which actually needs that
> > structure, thereby making the address of d5 known within.  And it
> > may even be in a called function where the ultimate update takes
> > place.
> > 
> > Is there any way to convey that information in a way that doesn't
> > involve a switch () { } statement, or determining the member offset,
> > casting my future-allocated pointer to char*, adding in that offset,
> > then re-casting back to its final form?
> > 
> > I'm looking for something like this "memberRef" ability, which conveys
> > the relative offset for the struct without manual mechanics:
> > 
> >     14:    struct SContainer? t;   // A member reference holder
> >     15:
> >     16:    if (some_test)
> >     17:        t = d5;             // Need to update d5
> >     18:  
> >     19:    // More instructions
> >     20:  
> >     21:    // Allocate pointer
> >     22:    struct SContainer* c = malloc(sizeof(struct SContainer));
> >     23:    if (c)
> >     24:    {
> >     25:        // Now I can update c->d5 without knowing what it was
> >     26:        // in 16: directly, but I simply use the t ?memberRef.
> >     26:        c->?t = ptr;
> >     27:        // At this point, c->d5 was set to ptr
> >     28:    }
> > 
> > The compiler would automatically convey some runtime checking on the
> > type to make sure I'm populating into something that's compatible.
> > 
> > Is there any ability to do this dynamically in C (or C++)?
> 
> I'll probably get complaints for saying this here...
> 
> Your hypothetical syntax is so close to the existing C++ syntax that
> I wonder if you have encountered it before and forgotten.

No, sir.  It occurred to me yesterday as the solution to a particular
problem I was having.  It took me a couple minutes to work out the
syntax I liked, but the idea was fully formed:  I needed member
references.

What is the name for the C++ feature?  I am calling mine "conveyable
member references."

> 14:     struct SData *SContainer::*t;  // A member reference holder
> 15:
> 16:     if (some_test)
> 17:         t = &SContainer::d5;       // Need to update d5
> ...
> 26:         c->*t = ptr;
> 27:         // At this point, c->d5 was set to ptr

[Rick faints, is carried over to a couch where smelling salts are
administered...]

WOW!  That is quite something.  [virtual pause to examine the code]  It
looks a little different.  In C++ it's defined as an SData-related entity.
In my version that is not a requirement.  It also requires the SContainer
in the &SContainer::d5 reference.  Mine derives from the assignment which
type it is, and then shorthands it.

I also like my syntax better. :-)

    struct SContainer? t;
    t = d5;
    c->?t  = ptr;    // With type checking
    c->??t = ptr;    // Without type checking, which is then
                     // basically a form of "ad hoc union," able
                     // to apply data at any point, for any reason.

Best regards,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#75286

FromPhilip Lantz <prl@canterey.us>
Date2015-11-07 11:35 -0800
Message-ID<MPG.30a7f24ca7f616cf8a@news.eternal-september.org>
In reply to#75250
Rick C. Hodgin wrote:
> 
> On Saturday, November 7, 2015 at 4:37:45 AM UTC-5, Philip Lantz wrote:
> > Rick C. Hodgin wrote:
> > > 
> > > I have a situation in C code where I know the member I need to update
> > > in a pointer to a struct, but I don't yet have the pointer allocated
> > > that I need to update, so I can't obtain its exact address yet.
> > > 
> > > Example:
> > > 
> > >     01:    extern struct SData;
> > >     02:  
> > >     03:    struct SContainer
> > >     04:    {
> > >     05:        struct SData*   d1;
> > >     06:        struct SData*   d2;
> > >     07:        struct SData*   d3;
> > >     08:        struct SData*   d4;
> > >     09:        struct SData*   d5;
> > >     10:        struct SData*   d6;
> > >     11:        struct SData*   d7;
> > >     12:        struct SData*   d8;
> > >     13:    };
> > >     14:  
> > >     15:    if (some_test)
> > >     16:        // I know here that I need to update d5
> > >     17:  
> > >     18:    // More instructions
> > >     19:  
> > >     20:    // Allocate pointer
> > >     21:    struct SContainer* c = malloc(sizeof(struct SContainer));
> > >     22:    if (c)
> > >     23:    {
> > >     24:        // Now I need to update c->d5, but how ??
> > >     25:    }
> > > 
> > > On 15: and 16:, I'm able to determine through logic that the member
> > > I need to update is d5, for example, within the struct SContainer
> > > structure.  I know that, but it will be many instructions later
> > > before I am able to allocate the pointer which actually needs that
> > > structure, thereby making the address of d5 known within.  And it
> > > may even be in a called function where the ultimate update takes
> > > place.
> > > 
> > > Is there any way to convey that information in a way that doesn't
> > > involve a switch () { } statement, or determining the member offset,
> > > casting my future-allocated pointer to char*, adding in that offset,
> > > then re-casting back to its final form?
> > > 
> > > I'm looking for something like this "memberRef" ability, which conveys
> > > the relative offset for the struct without manual mechanics:
> > > 
> > >     14:    struct SContainer? t;   // A member reference holder
> > >     15:
> > >     16:    if (some_test)
> > >     17:        t = d5;             // Need to update d5
> > >     18:  
> > >     19:    // More instructions
> > >     20:  
> > >     21:    // Allocate pointer
> > >     22:    struct SContainer* c = malloc(sizeof(struct SContainer));
> > >     23:    if (c)
> > >     24:    {
> > >     25:        // Now I can update c->d5 without knowing what it was
> > >     26:        // in 16: directly, but I simply use the t ?memberRef.
> > >     26:        c->?t = ptr;
> > >     27:        // At this point, c->d5 was set to ptr
> > >     28:    }
> > > 
> > > The compiler would automatically convey some runtime checking on the
> > > type to make sure I'm populating into something that's compatible.
> > > 
> > > Is there any ability to do this dynamically in C (or C++)?
> > 
> > I'll probably get complaints for saying this here...
> > 
> > Your hypothetical syntax is so close to the existing C++ syntax that
> > I wonder if you have encountered it before and forgotten.
> 
> No, sir.  It occurred to me yesterday as the solution to a particular
> problem I was having.  It took me a couple minutes to work out the
> syntax I liked, but the idea was fully formed:  I needed member
> references.
> 
> What is the name for the C++ feature?  I am calling mine "conveyable
> member references."

It's called a pointer to member.

> 
> > 14:     struct SData *SContainer::*t;  // A member reference holder
> > 15:
> > 16:     if (some_test)
> > 17:         t = &SContainer::d5;       // Need to update d5
> > ...
> > 26:         c->*t = ptr;
> > 27:         // At this point, c->d5 was set to ptr
> 
> [Rick faints, is carried over to a couch where smelling salts are
> administered...]
> WOW!  That is quite something. 

Amazing, isn't it.

> [virtual pause to examine the code]  It
> looks a little different.  In C++ it's defined as an SData-related entity.
> In my version that is not a requirement.

The whole point of using this instead of offsetof is for type-safety, so it
makes sense to specify the type of the object referenced.

> It also requires the SContainer
> in the &SContainer::d5 reference.  Mine derives from the assignment which
> type it is, and then shorthands it.

In C and C++ both, the type of an expression is completely independent of
context.

Thus, in

struct X { int a, b; }
struct Y { int b, c; }

int X::*t = &b;           // incorrect

the compiler isn't allowed to know from the context which b to use, so it
has to be

int X::*t = &X::b;


> I also like my syntax better. :-)

I'm not a fan of the question marks in your proposal, but I certainly
won't defend C++ syntax: I'm not sure I've ever seen uglier (though I'm
completely comfortable with reading and writing it).

[toc] | [prev] | [next] | [standalone]


#75290

From"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
Date2015-11-07 12:06 -0800
Message-ID<5b552ae9-9f5d-470e-b4d7-94520d903e5f@googlegroups.com>
In reply to#75286
Philip Lantz wrote:
> I'm not a fan of the question marks in your
> proposal, but I certainly won't defend C++
> syntax: I'm not sure I've ever seen uglier
> (though I'm completely comfortable with
> reading and writing it).

I'm open to alternatives. To me, the ? conveyed
that it wasn't an explicitly known member.

Best regards,
Rick C. Hodgin

[toc] | [prev] | [next] | [standalone]


#75291

FromIan Collins <ian-news@hotmail.com>
Date2015-11-08 09:17 +1300
Message-ID<da74j7FjinnU3@mid.individual.net>
In reply to#75286
Philip Lantz wrote:
>
> I'm not a fan of the question marks in your proposal, but I certainly
> won't defend C++ syntax: I'm not sure I've ever seen uglier (though I'm
> completely comfortable with reading and writing it).

The ugliness is a useful reminder to find a different solution :) 
Pointers to members are rarely used in C++ code.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#75298

FromPhilip Lantz <prl@canterey.us>
Date2015-11-07 13:51 -0800
Message-ID<MPG.30a8124d573ebe38f@news.eternal-september.org>
In reply to#75291
Ian Collins wrote:
> 
> Philip Lantz wrote:
> >
> > I'm not a fan of the question marks in your proposal, but I certainly
> > won't defend C++ syntax: I'm not sure I've ever seen uglier (though I'm
> > completely comfortable with reading and writing it).
> 
> The ugliness is a useful reminder to find a different solution :) 
> Pointers to members are rarely used in C++ code.

Oh, I should have been more clear--I was talking about the ugliness of
*all* of C++ syntax, not just the pointer-to-member syntax. For example:

typename AvlTree<K,V>::TreeNode *AvlTree<K,V>::remove_recursive(AvlTree<K,V>::TreeNode *curr,

(Just to be clear, I use C++ all the time, and I'm pretty happy with it.)

[toc] | [prev] | [next] | [standalone]


#75301

FromIan Collins <ian-news@hotmail.com>
Date2015-11-08 11:18 +1300
Message-ID<da7bm8FjinoU1@mid.individual.net>
In reply to#75298
Philip Lantz wrote:
> Ian Collins wrote:
>>
>> Philip Lantz wrote:
>>>
>>> I'm not a fan of the question marks in your proposal, but I certainly
>>> won't defend C++ syntax: I'm not sure I've ever seen uglier (though I'm
>>> completely comfortable with reading and writing it).
>>
>> The ugliness is a useful reminder to find a different solution :)
>> Pointers to members are rarely used in C++ code.
>
> Oh, I should have been more clear--I was talking about the ugliness of
> *all* of C++ syntax, not just the pointer-to-member syntax. For example:
>
> typename AvlTree<K,V>::TreeNode *AvlTree<K,V>::remove_recursive(AvlTree<K,V>::TreeNode *curr,
>
> (Just to be clear, I use C++ all the time, and I'm pretty happy with it.)

Thank goodness for "auto" :)

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#75615

Fromraltbos@xs4all.nl (Richard Bos)
Date2015-11-10 16:58 +0000
Message-ID<564221e1.7974250@news.xs4all.nl>
In reply to#75301
Ian Collins <ian-news@hotmail.com> wrote:

> Philip Lantz wrote:
> > Ian Collins wrote:
> >> Philip Lantz wrote:
> >>>
> >>> I'm not a fan of the question marks in your proposal, but I certainly
> >>> won't defend C++ syntax: I'm not sure I've ever seen uglier (though I'm
> >>> completely comfortable with reading and writing it).
> >>
> >> The ugliness is a useful reminder to find a different solution :)
> >> Pointers to members are rarely used in C++ code.
> >
> > Oh, I should have been more clear--I was talking about the ugliness of
> > *all* of C++ syntax, not just the pointer-to-member syntax. For example:
> >
> > typename AvlTree<K,V>::TreeNode *AvlTree<K,V>::remove_recursive(AvlTree<K,V>::TreeNode *curr,
> >
> > (Just to be clear, I use C++ all the time, and I'm pretty happy with it.)
> 
> Thank goodness for "auto" :)

Thank goodness "auto" is essentially meaningless in C++...

Richard

[toc] | [prev] | [next] | [standalone]


#75628

FromKeith Thompson <kst-u@mib.org>
Date2015-11-10 09:15 -0800
Message-ID<lnziylu675.fsf@kst-u.example.com>
In reply to#75615
raltbos@xs4all.nl (Richard Bos) writes:
[...]
> Thank goodness "auto" is essentially meaningless in C++...

Did you mean to say that "auto" is essentially meaningless in C?

<OT>
C++, as of the 2011 standard, has changed the meaning of "auto"; it's
not meaningless at all.

http://en.cppreference.com/w/cpp/language/auto
</OT>

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#75662

Fromraltbos@xs4all.nl (Richard Bos)
Date2015-11-10 19:05 +0000
Message-ID<56423fca.15631296@news.xs4all.nl>
In reply to#75628
Keith Thompson <kst-u@mib.org> wrote:

> raltbos@xs4all.nl (Richard Bos) writes:
> [...]
> > Thank goodness "auto" is essentially meaningless in C++...
> 
> Did you mean to say that "auto" is essentially meaningless in C?

Yes - sorry.

Richard

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web