Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #75135 > unrolled thread
| Started by | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| First post | 2015-11-06 09:27 -0800 |
| Last post | 2015-11-10 12:20 -0500 |
| Articles | 20 on this page of 21 — 9 participants |
Back to article view | Back to comp.lang.c
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 →
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-11-06 09:27 -0800 |
| Subject | Help 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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-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]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-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]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-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]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-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