Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #75010 > unrolled thread
| Started by | fl <rxjwg98@gmail.com> |
|---|---|
| First post | 2015-11-05 12:21 -0800 |
| Last post | 2015-12-06 15:31 -0800 |
| Articles | 16 — 7 participants |
Back to article view | Back to comp.lang.c
Question about type cast in queue code fl <rxjwg98@gmail.com> - 2015-11-05 12:21 -0800
Re: Question about type cast in queue code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-05 20:43 +0000
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-11-05 16:10 -0500
Re: Question about type cast in queue code fl <rxjwg98@gmail.com> - 2015-11-05 16:50 -0800
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-11-05 21:37 -0500
Re: Question about type cast in queue code Philip Lantz <prl@canterey.us> - 2015-11-06 20:37 -0800
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-11-07 00:20 -0500
Re: Question about type cast in queue code Philip Lantz <prl@canterey.us> - 2015-11-07 11:51 -0800
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-11-07 15:34 -0500
Re: Question about type cast in queue code Philip Lantz <prl@canterey.us> - 2015-11-07 13:42 -0800
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-11-07 16:53 -0500
Re: Question about type cast in queue code David Thompson <dave.thompson2@verizon.net> - 2015-12-06 07:56 -0500
Re: Question about type cast in queue code Keith Thompson <kst-u@mib.org> - 2015-12-06 12:28 -0800
Re: Question about type cast in queue code Philip Lantz <prl@canterey.us> - 2015-12-06 13:29 -0800
Re: Question about type cast in queue code James Kuyper <jameskuyper@verizon.net> - 2015-12-06 18:18 -0500
Re: Question about type cast in queue code supercat@casperkitty.com - 2015-12-06 15:31 -0800
| From | fl <rxjwg98@gmail.com> |
|---|---|
| Date | 2015-11-05 12:21 -0800 |
| Subject | Question about type cast in queue code |
| Message-ID | <b3348687-a459-4ebc-89fe-5ff59f4bd55b@googlegroups.com> |
Hi,
I try to write a queue application on Tiva-C 1294 board. I find the following line is difficult to understand:
elem != (Queue_Elem *)myQ;
myQ is a Queue_Handletype variable. Type cast (Queue_Elem *) does make it work. But I feel it is beyond of my understanding now.
Why and how does the type cast work for this?
Thanks,
/* This structure can be added to a Queue because the first field is a Queue_Elem. */
typedef struct Rec {
Queue_Elem elem;
Int data;
} Rec;
Queue_Handle myQ;
...
Queue_Elem *elem;
for (elem = Queue_head(myQ); elem != (Queue_Elem *)myQ;
elem = Queue_next(elem)) {
...
}
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-05 20:43 +0000 |
| Message-ID | <87io5gyy77.fsf@bsb.me.uk> |
| In reply to | #75010 |
fl <rxjwg98@gmail.com> writes:
<snip>
> /* This structure can be added to a Queue because the first field is a
> Queue_Elem. */
> typedef struct Rec {
> Queue_Elem elem;
> Int data;
> } Rec;
This is a common technique to allow structures like lists and queues to
hold arbitrary user-defined data. Unfortunately I don't know if it has
a common name you can use to search for examples.
> Queue_Handle myQ;
> ...
>
> Queue_Elem *elem;
> for (elem = Queue_head(myQ); elem != (Queue_Elem *)myQ;
> elem = Queue_next(elem)) {
> ...
> }
Unfortunately you don't show the definition of the type Queue_Handle so
it's hard to know what relation is has with a Queue_Elem. If you are
using the same included struct trick that Rec uses, the test you
want is probably
else != &myO.elem
but that is no more than a wild guess right now.
If possible, post a complete program or at least post the definitions of
all the types, variable and so on that are referred to.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-05 16:10 -0500 |
| Message-ID | <n1ggg3$ag8$1@dont-email.me> |
| In reply to | #75010 |
On 11/05/2015 03:21 PM, fl wrote: > Hi, > > I try to write a queue application on Tiva-C 1294 board. I find the following line is difficult to understand: > > elem != (Queue_Elem *)myQ; > > myQ is a Queue_Handletype variable. Type cast (Queue_Elem *) does make it work. But I feel it is beyond of my understanding now. > Why and how does the type cast work for this? The code you've provided is insufficient to answer that question. At a minimum, we need to know the definition of the Queue_Handle type, and knowing the definition of the Queue_Elem type might also be useful. It would also help if you could articulate better what feature of this code makes it hard for you to understand. One way to approach that question is to give us an example of similar code that you do understand; the difference between the code you do understand and the code you don't understand could give us some clue as to what it is that is giving you trouble understanding it. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | fl <rxjwg98@gmail.com> |
|---|---|
| Date | 2015-11-05 16:50 -0800 |
| Message-ID | <8c81e1b0-cd60-44a9-8d48-21b266a97ce9@googlegroups.com> |
| In reply to | #75020 |
On Thursday, November 5, 2015 at 4:10:42 PM UTC-5, James Kuyper wrote:
> On 11/05/2015 03:21 PM, fl wrote:
> > Hi,
> >
> > I try to write a queue application on Tiva-C 1294 board. I find the following line is difficult to understand:
> >
> > elem != (Queue_Elem *)myQ;
> >
> > myQ is a Queue_Handletype variable. Type cast (Queue_Elem *) does make it work. But I feel it is beyond of my understanding now.
> > Why and how does the type cast work for this?
>
> The code you've provided is insufficient to answer that question. At a
> minimum, we need to know the definition of the Queue_Handle type, and
> knowing the definition of the Queue_Elem type might also be useful.
>
> It would also help if you could articulate better what feature of this
> code makes it hard for you to understand. One way to approach that
> question is to give us an example of similar code that you do
> understand; the difference between the code you do understand and the
> code you don't understand could give us some clue as to what it is that
> is giving you trouble understanding it.
> --
> James Kuyper
Thanks for the replies. Due to the complexities of the project, there is not
a clearly definition of the Queue_Elem. But I think its description, see
below could help. My understanding difficulties are in the conversion of
handler 'myQ' to type 'Queue_Elem':
elem != (Queue_Elem *)myQ;
After I think a while of the type definition 'Rec', I guess that
'Queue_Elem _elem;' is the first element of the struct is crucial. This
arrangement makes the address of 'Queue_Elem' and Rec pointer (such as rp)
is the same.
Change the struct definition to:
typedef struct Rec {
Int data;
Queue_Elem _elem;
} Rec;
will invalidate the original type casting:
elem != (Queue_Elem *)myQ;
Am I right?
Thanks,
........
The Queue module makes available a set of functions that manipulate queue objects accessed through handles of type Queue_Handle. Each queue contains a linked sequence of zero or more elements referenced through variables of type Queue_Elem, which are embedded as the first field within a structure.
In the Queue API descriptions, the APIs which disable interrupts before modifying the Queue are noted as "atomic", while APIs that do not disable interrupts are "non-atomic".
Queues are represented as doubly-linked lists, so calls to Queue_next or Queue_prev can loop continuously over the Queue. The following code demonstrates one way to iterate over a Queue once from beginning to end. In this example, 'myQ' is a Queue_Handle.
Queue_Elem *elem;
for (elem = Queue_head(myQ);
elem != (Queue_Elem *)myQ;
elem = Queue_next(elem)) {
...
}
Below is a simple example of how to create a Queue, enqueue two elements, and dequeue the elements until the queue is empty:
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <../knl/Queue.h>
typedef struct Rec {
Queue_Elem _elem;
Int data;
} Rec;
Int main(Int argc, Char *argv[])
{
Queue_Handle q;
Rec r1, r2;
Rec* rp;
r1.data = 100;
r2.data = 200;
// create a Queue instance 'q'
q = Queue_create(NULL, NULL);
// enQ a couple of records
Queue_enqueue(q, &r1._elem);
Queue_enqueue(q, &r2._elem);
// deQ the records and print their data values until Q is empty
while (!Queue_empty(q)) {
rp = Queue_dequeue(q);
System_printf("rec: %d\n", rp->data);
}
System_exit(0);
return (0);
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-05 21:37 -0500 |
| Message-ID | <n1h3lu$6t1$1@dont-email.me> |
| In reply to | #75036 |
On 11/05/2015 07:50 PM, fl wrote: > On Thursday, November 5, 2015 at 4:10:42 PM UTC-5, James Kuyper wrote: >> On 11/05/2015 03:21 PM, fl wrote: >>> Hi, >>> >>> I try to write a queue application on Tiva-C 1294 board. I find the following line is difficult to understand: >>> >>> elem != (Queue_Elem *)myQ; >>> >>> myQ is a Queue_Handletype variable. Type cast (Queue_Elem *) does make it work. But I feel it is beyond of my understanding now. >>> Why and how does the type cast work for this? >> >> The code you've provided is insufficient to answer that question. At a >> minimum, we need to know the definition of the Queue_Handle type, and >> knowing the definition of the Queue_Elem type might also be useful. >> >> It would also help if you could articulate better what feature of this >> code makes it hard for you to understand. One way to approach that >> question is to give us an example of similar code that you do >> understand; the difference between the code you do understand and the >> code you don't understand could give us some clue as to what it is that >> is giving you trouble understanding it. >> -- >> James Kuyper > > Thanks for the replies. Due to the complexities of the project, there is not > a clearly definition of the Queue_Elem. That is simply impossible. You might not be clear about the definition of Queue_Elem, but C compilers don't tolerate unclear definitions. Somewhere in the source code is a precise, perfectly clear definition for Queue_Elem, or code that uses Queue_Elem wouldn't be able to compile. You've just got to find out where that definition is. In any event, Queue_Elem is less important than Queue_Handle. Without a definition for Queue_Handle, it's impossible to make any meaningful comments addressing your question. Can you locate that definition? ... > #include <xdc/std.h> > #include <xdc/runtime/System.h> > > #include <../knl/Queue.h> It seems likely that you'll be able to find the definition for Queue_Handle in that header file. If you can't find the header file, there's another approach that might work. Many compilers have an option to produce pre-processed output only. For instance, for gcc the relevant option is -E. If you could create a program file that contains only the above #include statement, and then process it with gcc -E, the output should contain a definition for Queue_Handle. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-11-06 20:37 -0800 |
| Message-ID | <MPG.30a71fd29d392c1b84@news.eternal-september.org> |
| In reply to | #75042 |
James Kuyper wrote:
>
> fl wrote:
> > Thanks for the replies. Due to the complexities of the project, there
> > is not a clearly definition of the Queue_Elem.
>
> That is simply impossible. You might not be clear about the definition
> of Queue_Elem, but C compilers don't tolerate unclear definitions.
> Somewhere in the source code is a precise, perfectly clear definition
> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
> compile. You've just got to find out where that definition is.
I usually try to avoid picking nits, but I have to throw this at you:
struct Queue_Elem;
int main()
{
Queue_Elem *elem = 0;
void *myQ = 0;
elem != (Queue_Elem *)myQ;
return 0;
}
:-)
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-07 00:20 -0500 |
| Message-ID | <n1k1jb$t4a$1@dont-email.me> |
| In reply to | #75213 |
On 11/06/2015 11:37 PM, Philip Lantz wrote:
> James Kuyper wrote:
>>
>> fl wrote:
>>> Thanks for the replies. Due to the complexities of the project, there
>>> is not a clearly definition of the Queue_Elem.
>>
>> That is simply impossible. You might not be clear about the definition
>> of Queue_Elem, but C compilers don't tolerate unclear definitions.
>> Somewhere in the source code is a precise, perfectly clear definition
>> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
>> compile. You've just got to find out where that definition is.
>
> I usually try to avoid picking nits, but I have to throw this at you:
>
> struct Queue_Elem;
>
> int main()
> {
> Queue_Elem *elem = 0;
> void *myQ = 0;
>
> elem != (Queue_Elem *)myQ;
>
> return 0;
> }
You're right - it's possible to write code using pointers to structs,
without having a definition of the struct type itself. But while that
might be precisely what's going on inside fl's code, his code calls
routines named Queue_head(), Queue_next(), Queue_create() and
Queue_enqueue(). At least one of those routines must know the definition
of Queue_Handle, and without that definition, I can't answer fl's question.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-11-07 11:51 -0800 |
| Message-ID | <MPG.30a7f6206a9f01358b@news.eternal-september.org> |
| In reply to | #75215 |
James Kuyper wrote:
> Philip Lantz wrote:
> > James Kuyper wrote:
> >>
> >> fl wrote:
> >>> Thanks for the replies. Due to the complexities of the project, there
> >>> is not a clearly definition of the Queue_Elem.
> >>
> >> That is simply impossible. You might not be clear about the definition
> >> of Queue_Elem, but C compilers don't tolerate unclear definitions.
> >> Somewhere in the source code is a precise, perfectly clear definition
> >> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
> >> compile. You've just got to find out where that definition is.
> >
> > I usually try to avoid picking nits, but I have to throw this at you:
> >
> > struct Queue_Elem;
> >
> > int main()
> > {
> > Queue_Elem *elem = 0;
> > void *myQ = 0;
> >
> > elem != (Queue_Elem *)myQ;
> >
> > return 0;
> > }
>
> You're right - it's possible to write code using pointers to structs,
> without having a definition of the struct type itself. But while that
> might be precisely what's going on inside fl's code, his code calls
> routines named Queue_head(), Queue_next(), Queue_create() and
> Queue_enqueue(). At least one of those routines must know the definition
> of Queue_Handle ...
We were talking about Queue_Elem, not Queue_Handle. None of those
routines need to know the definition of Queue_Elem; it could be a
completely abstract type, intended only for the user of the queue
code, and which is cast to a concrete type inside the queue functions
whenever it is used.
Or, the queue functions could be in a library, the source of which he
has no access to.
(I'm only picking on the words "simply impossible." If you had said
"unlikely", I wouldn't have said anything.)
Philip
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-07 15:34 -0500 |
| Message-ID | <563E6039.5000606@verizon.net> |
| In reply to | #75287 |
On 11/07/2015 02:51 PM, Philip Lantz wrote:
> James Kuyper wrote:
>> Philip Lantz wrote:
>>> James Kuyper wrote:
>>>>
>>>> fl wrote:
>>>>> Thanks for the replies. Due to the complexities of the project, there
>>>>> is not a clearly definition of the Queue_Elem.
>>>>
>>>> That is simply impossible. You might not be clear about the definition
>>>> of Queue_Elem, but C compilers don't tolerate unclear definitions.
>>>> Somewhere in the source code is a precise, perfectly clear definition
>>>> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
>>>> compile. You've just got to find out where that definition is.
>>>
>>> I usually try to avoid picking nits, but I have to throw this at you:
>>>
>>> struct Queue_Elem;
>>>
>>> int main()
>>> {
>>> Queue_Elem *elem = 0;
>>> void *myQ = 0;
>>>
>>> elem != (Queue_Elem *)myQ;
>>>
>>> return 0;
>>> }
>>
>> You're right - it's possible to write code using pointers to structs,
>> without having a definition of the struct type itself. But while that
>> might be precisely what's going on inside fl's code, his code calls
>> routines named Queue_head(), Queue_next(), Queue_create() and
>> Queue_enqueue(). At least one of those routines must know the definition
>> of Queue_Handle ...
>
> We were talking about Queue_Elem, not Queue_Handle.
Feel free to talk about something else if you wish, but whenever I have
mentioned Queue_Handle, I did so because I was in fact talking about
Queue_Handle, not Queue_Elem. I talked about Queue_Elem only because fl
ignored my main question, which was about the definition of
Queue_Handle, and instead gave a non-answer to my secondary question
about the definition of Queue_Elem.
fl said that Queue_Handle was the type of myQ, and it is therefore a
type whose definition is relevant to the answer of his question. In
particular, if Queue_Handle is a pointer to a struct whose first member
has the type Queue_Elem, then I don't need to know anything more about
the meaning of Queue_Elem in order to answer his question. It works the
other way, too: if Queue_Elem is a struct type, and the first member of
that struct has the same type that Queue_Handle points at, I can also
explain how the code is working, and I don't need to know anything more
about the type that Queue_Handle points at. If Queue_Elem has character
type, or if Queue_Handle points at a character type, I can also explain
it. However, I can't choose the correct explanation until fl tells me
what the relevant definitions are.
> None of those
> routines need to know the definition of Queue_Elem; it could be a
> completely abstract type, intended only for the user of the queue
> code, and which is cast to a concrete type inside the queue functions
> whenever it is used.
In order to perform that cast, those functions need to know what that
concrete type is.
> Or, the queue functions could be in a library, the source of which he
> has no access to.
True. However, that inaccessible source code must know what the
definition of that type is. That code might be in a language other than
C, and might therefore define the type using different syntax than C
uses. It might not even be a named type; the definition would simply be
implicit in the instructions used to access the value of the
corresponding object - but that code must know that definition.
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-11-07 13:42 -0800 |
| Message-ID | <MPG.30a81022299def368e@news.eternal-september.org> |
| In reply to | #75293 |
James Kuyper wrote:
>
> On 11/07/2015 02:51 PM, Philip Lantz wrote:
> > James Kuyper wrote:
> >> Philip Lantz wrote:
> >>> James Kuyper wrote:
> >>>>
> >>>> fl wrote:
> >>>>> Thanks for the replies. Due to the complexities of the project, there
> >>>>> is not a clearly definition of the Queue_Elem.
> >>>>
> >>>> That is simply impossible. You might not be clear about the definition
> >>>> of Queue_Elem, but C compilers don't tolerate unclear definitions.
> >>>> Somewhere in the source code is a precise, perfectly clear definition
> >>>> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
> >>>> compile. You've just got to find out where that definition is.
> >>>
> >>> I usually try to avoid picking nits, but I have to throw this at you:
> >>>
> >>> struct Queue_Elem;
> >>>
> >>> int main()
> >>> {
> >>> Queue_Elem *elem = 0;
> >>> void *myQ = 0;
> >>>
> >>> elem != (Queue_Elem *)myQ;
> >>>
> >>> return 0;
> >>> }
> >>
> >> You're right - it's possible to write code using pointers to structs,
> >> without having a definition of the struct type itself. But while that
> >> might be precisely what's going on inside fl's code, his code calls
> >> routines named Queue_head(), Queue_next(), Queue_create() and
> >> Queue_enqueue(). At least one of those routines must know the definition
> >> of Queue_Handle ...
> >
> > We were talking about Queue_Elem, not Queue_Handle.
>
> Feel free to talk about something else if you wish, but whenever I have
> mentioned Queue_Handle, I did so because I was in fact talking about
> Queue_Handle, not Queue_Elem.
It's right there in the quotes above, but I'll quote it again:
> >>> James Kuyper wrote:
> >>>> fl wrote:
> >>>>> Thanks for the replies. Due to the complexities of the project, there
> >>>>> is not a clearly definition of the Queue_Elem.
> >>>>
> >>>> That is simply impossible.
That is the *only* part of this thread that I have been responding to.
And I acknowledged that it is a nit (and hence off the main point), right
in my original comment. (Also shown in the quotes above.)
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-07 16:53 -0500 |
| Message-ID | <563E72DC.6080204@verizon.net> |
| In reply to | #75297 |
On 11/07/2015 04:42 PM, Philip Lantz wrote: > James Kuyper wrote: >> >> On 11/07/2015 02:51 PM, Philip Lantz wrote: .... >>> We were talking about Queue_Elem, not Queue_Handle. >> >> Feel free to talk about something else if you wish, but whenever I have >> mentioned Queue_Handle, I did so because I was in fact talking about >> Queue_Handle, not Queue_Elem. > > It's right there in the quotes above, but I'll quote it again: >>>>> James Kuyper wrote: >>>>>> fl wrote: >>>>>>> Thanks for the replies. Due to the complexities of the project, there >>>>>>> is not a clearly definition of the Queue_Elem. >>>>>> >>>>>> That is simply impossible. > > That is the *only* part of this thread that I have been responding to. Perhaps - but it's not the only part of this thread I was talking about when answering your responses. The fact that some part of the code must know the definition of Queue_Handle is very relevant to what I was talking about, however irrelevant it might have been to what you were talking about. Also, what you were saying about Queue_Elem was, as far as I can tell, equally true about the type that Queue_Handle points at (assuming that it is a pointer type rather than an integer type), so I don't really see the point in your decision to restrict your own comments to Queue_Elem.
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2015-12-06 07:56 -0500 |
| Message-ID | <d3c86bhci7p71v54e9ujpnq7cvt9f2k81g@4ax.com> |
| In reply to | #75213 |
On Fri, 6 Nov 2015 20:37:10 -0800, Philip Lantz <prl@canterey.us>
wrote:
> James Kuyper wrote:
> >
> > fl wrote:
> > > Thanks for the replies. Due to the complexities of the project, there
> > > is not a clearly definition of the Queue_Elem.
> >
> > That is simply impossible. You might not be clear about the definition
> > of Queue_Elem, but [it's there somewhere]
>
> I usually try to avoid picking nits, but I have to throw this at you:
>
> struct Queue_Elem;
>
> int main()
> {
> Queue_Elem *elem = 0;
> void *myQ = 0;
>
> elem != (Queue_Elem *)myQ;
>
> return 0;
> }
>
As long as we're nitpicking, in C you need something like
typedef struct new_tag_name Queue_Elem;
/* new_tag_name MAY be Queue_Elem but need not */
In C++ a tag works almost like a typedef. Not C.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-12-06 12:28 -0800 |
| Message-ID | <lnd1ujpbi5.fsf@kst-u.example.com> |
| In reply to | #77969 |
David Thompson <dave.thompson2@verizon.net> writes:
> On Fri, 6 Nov 2015 20:37:10 -0800, Philip Lantz <prl@canterey.us>
> wrote:
[...]
>> struct Queue_Elem;
>>
>> int main()
>> {
>> Queue_Elem *elem = 0;
>> void *myQ = 0;
>>
>> elem != (Queue_Elem *)myQ;
>>
>> return 0;
>> }
>>
> As long as we're nitpicking, in C you need something like
>
> typedef struct new_tag_name Queue_Elem;
> /* new_tag_name MAY be Queue_Elem but need not */
No, you don't *need* a typedef. You can just refer to the type by
its original name, which happens to be `struct Queue_Elem`. Using a
typedef to give it a new name `Queue_Elem` is entirely optional.
> In C++ a tag works almost like a typedef. Not C.
--
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 | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-12-06 13:29 -0800 |
| Message-ID | <MPG.30ce487630a1944abf@news.eternal-september.org> |
| In reply to | #77996 |
Keith Thompson wrote:
> David Thompson writes:
> > On Fri, 6 Nov 2015 20:37:10 -0800, Philip Lantz wrote:
> >> struct Queue_Elem;
> >>
> >> int main()
> >> {
> >> Queue_Elem *elem = 0;
> >> void *myQ = 0;
> >>
> >> elem != (Queue_Elem *)myQ;
> >>
> >> return 0;
> >> }
> >>
> > As long as we're nitpicking, in C you need something like
> >
> > typedef struct new_tag_name Queue_Elem;
> > /* new_tag_name MAY be Queue_Elem but need not */
>
> No, you don't *need* a typedef. You can just refer to the type by
> its original name, which happens to be `struct Queue_Elem`.
Yes, that's what I intended to write. I've been writing so
much C++ lately that I overlooked it.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-12-06 18:18 -0500 |
| Message-ID | <5664C24E.7050204@verizon.net> |
| In reply to | #75042 |
James Kuyper wrote:
>
> fl wrote:
> > Thanks for the replies. Due to the complexities of the project, there
> > is not a clearly definition of the Queue_Elem.
>
> That is simply impossible. You might not be clear about the definition
> of Queue_Elem, but C compilers don't tolerate unclear definitions.
> Somewhere in the source code is a precise, perfectly clear definition
> for Queue_Elem, or code that uses Queue_Elem wouldn't be able to
> compile. You've just got to find out where that definition is.
Given the recently renewed interest in this thread, I decided to go
looking to see if I could find the definitions that fl claimed are
unavailable. A Google search brought me to >
<http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/sysbios/6_40_04_47/exports/bios_6_40_04_47/docs/cdoc/ti/sysbios/knl/Queue.html#xdoc-desc>.
I've no idea whether that's relevant - the names are sufficiently
generic that it's possible, though unlikely, that fl was using some
other library that uses the same names. ti.com is a domain name where I
can also find references to the Tiva-C 1294 board that fl referred to,
but I did not manage to find a direct connection between the Tiva-C 1294
and the URL I gave above. Possibly I didn't look hard enough.
Unless and until fl chooses to enlighten us otherwise, I'll go ahead on
the assumption that this documentation is relevant. If it isn't, my
analysis of this documentation will at least provide a model that fl can
use to analyze the correct documentation.
The only items from that page needed to deal with fl's question are:
> typedef struct Queue_Elem {
> Queue_Elem *next;
> Queue_Elem *prev;
> } Queue_Elem;
and
> typedef struct Queue_Object Queue_Object;
> // Opaque internal representation of an instance object
>
> typedef Queue_Object *Queue_Handle;
> // Client reference to an instance object
fl's original question was:
> I try to write a queue application on Tiva-C 1294 board. I find the following line is difficult to understand:
>
> elem != (Queue_Elem *)myQ;
>
> myQ is a Queue_Handletype variable. Type cast (Queue_Elem *) does make it work. But I feel it is beyond of my understanding now.
> Why and how does the type cast work for this?
Replacing typedefs with their original types, this becomes:
struct Queue_Object *myQ;
and
elem != (struct Queue_Elem*)myQ;
Now, since struct Queue_Object is an opaque type, it's not possible to
be certain whether this code has well-defined behavior. If we assume
that myQ is correctly aligned to allow conversion to struct Queue_Elem*,
then 6.3.2.3p7 guarantees that (struct Queue_Object*)elem == myQ.
However, it seem likely that this conversion was performed for reasons
other than simply converting it back again. More information than simply
"correct alignment" is needed to justify dereferencing elem.
What's needed is the type of the first member of struct Queue_Object. If
we assume that *elem has well-defined behavior, we can work backwards to
determine what the possible types for that member are. There are
infinitely many such types, but that infinite set is easy to
characterize; it's only infinite because the definition involves
recursion, and in real life it's unlikely that the recursion goes very
far - even one step of recursion is pretty unlikely.
The first member of a struct Queue_Object must be either a struct
Queue_Elem object, or recursively, either another struct whose first
member is of struct Queue_Elem type, or a union where any member is of
that type. If that weren't the case, the only thing you could safely do
with *elem is &*elem.
If a union is involved, then reading elem->next or elem->prev requires
that the last write to that union must have left it containing a bit
pattern that can be interpreted as a representing a valid value for the
pointer that is read. There's other ways to achieve that result, but the
simplest is if the last write used the struct Queue_Elem member of that
union (6.5.2.3p3 and footnote 95).
In that case, this code is relying upon (6.7.2.1p11): "A pointer to a
structure object, suitably converted, points to its initial member (or
if that member is a bit-field, then to the unit in which it resides),
and vice versa." and possibly upon (6.7.2.1p16) "A pointer to a union
object, suitably converted, points to each of its members (or if a
member is a bitfield, then to the unit in which it resides), and vice
versa."
Thus, the result of the conversion is that elem is now pointing at a
struct Queue_Elem object that, one way or another, occupies the very
beginning of struct Queue_Object.
Another case that should apply is if the first member is an array of
struct Queue_Elem, but there's no clause in the standard defining the
behavior of the conversions from a pointer to an array to a pointer to
it's element type. We all "know" that this is a perfectly well-defined
conversion that results in a pointer to the first element of the array
(and that the reverse conversion is also safe) - which would combine
with 6.7.2.1p11 to allow such code. However, when I've asked, repeatedly
over the years, for a citation from the standard supporting that
"knowledge", all I've gotten was silence. I can't find it. It should be
somewhere in 6.7.6.2.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-12-06 15:31 -0800 |
| Message-ID | <65ca6da5-790a-46da-868f-db6141dd68e7@googlegroups.com> |
| In reply to | #78009 |
On Sunday, December 6, 2015 at 5:18:47 PM UTC-6, James Kuyper wrote: > What's needed is the type of the first member of struct Queue_Object. If > we assume that *elem has well-defined behavior... Well-defined in what language? ANSI C, or the language described by K&R 2, which is ANSI C but with an extension that, among other things, allows a pointer to any structure to be used as a pointer to any other structure with the same initial sequence, provided that it is only used to access members within that initial sequence?
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web