Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #158441 > unrolled thread
| Started by | T <T@invalid.invalid> |
|---|---|
| First post | 2021-01-18 17:01 -0800 |
| Last post | 2021-01-25 21:20 -0800 |
| Articles | 20 on this page of 33 — 9 participants |
Back to article view | Back to comp.lang.c
I need help understand a struct T <T@invalid.invalid> - 2021-01-18 17:01 -0800
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 01:37 +0000
Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-18 17:41 -0800
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 01:52 +0000
Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-18 18:03 -0800
Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-18 19:00 -0800
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 11:34 +0000
Re: I need help understand a struct Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-19 04:18 -0800
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 13:01 +0000
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-19 21:39 +0000
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-19 23:20 +0000
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 00:25 +0000
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-20 12:42 +0000
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 17:39 +0000
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-20 19:32 +0000
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-20 20:45 +0000
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-21 16:12 +0000
Re: I need help understand a struct Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-21 17:10 +0000
Re: I need help understand a struct Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-01-21 11:51 -0800
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-22 12:26 +0000
Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-21 20:16 +0000
Re: I need help understand a struct Bart <bc@freeuk.com> - 2021-01-21 23:04 +0000
Re: I need help understand a struct "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2021-01-25 11:59 -0800
Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-25 21:18 -0800
Re: I need help understand a struct Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-27 07:53 -0800
Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-27 08:35 -0800
Re: I need help understand a struct Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-28 07:48 -0800
Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-28 09:25 -0800
Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 18:03 +0000
Re: I need help understand a struct Guillaume <message@bottle.org> - 2021-01-28 20:46 +0100
Re: I need help understand a struct Kaz Kylheku <563-365-8930@kylheku.com> - 2021-01-28 21:31 +0000
Re: I need help understand a struct Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-29 11:15 -0800
Re: I need help understand a struct T <T@invalid.invalid> - 2021-01-25 21:20 -0800
Page 1 of 2 [1] 2 Next page →
| From | T <T@invalid.invalid> |
|---|---|
| Date | 2021-01-18 17:01 -0800 |
| Subject | I need help understand a struct |
| Message-ID | <ru5b0m$rm6$1@dont-email.me> |
Hi All,
https://gitlab.freedesktop.org/xorg/app/xclipboard/-/blob/master/xclipboard.c
66: typedef struct _Clip {
67: struct _Clip *next, *prev;
68: char *clip;
69: char *filename;
70: size_t avail;
71: } ClipRec, *ClipPtr;
Okay now I am confused. What??? Yes, AGAIN!
66 defines a structure called "_Clip". So far
so good
67 look like it is doing it again inside
the original definition. Is this a structure
embedded in another structure reusing the
same name ????
68 & 69 look like they a declaring pointers to
a character. Are not pointers usually
int64's?
70 What is an "avail"? Some kind of structure?
71 looks like it is returning two somethings
from the structure definition. Is this a
function or a structure or both?
Yours in confusion,
-T
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-19 01:37 +0000 |
| Message-ID | <87h7nd671f.fsf@bsb.me.uk> |
| In reply to | #158441 |
T <T@invalid.invalid> writes:
> https://gitlab.freedesktop.org/xorg/app/xclipboard/-/blob/master/xclipboard.c
>
> 66: typedef struct _Clip {
> 67: struct _Clip *next, *prev;
> 68: char *clip;
> 69: char *filename;
> 70: size_t avail;
> 71: } ClipRec, *ClipPtr;
>
> Okay now I am confused. What??? Yes, AGAIN!
>
> 66 defines a structure called "_Clip". So far
> so good
It's a little bit more than that. The typedef means that then whole
declaration will also define some "type names" -- aliases for types.
Putting that aside, yes, struct X { ... } is how a structure is defined.
The definition says what types of object are contained in an instance of
the structure. These are called the members.
> 67 look like it is doing it again inside
> the original definition. Is this a structure
> embedded in another structure reusing the
> same name ????
Without the { ... } no structure is being defined. Instead, the type
"struct _Clip" is used to declare objects -- in this case two members
called next and prev. But the type of these members is not "struct
_Clip". It is "pointer to struct _Clip". That's what the * in front of
the declared name means.
So a struct _Clip contains two pointers to other struct _Clip objects.
This is clearly going to be a doubly linked list.
> 68 & 69 look like they a declaring pointers to
> a character. Are not pointers usually
> int64's?
A pointer a is derived type in C. You can have a pointer to a
character, a pointer to an int or, as I've just described, a pointer to
a struct object.
> 70 What is an "avail"? Some kind of structure?
No, it is just an unsigned integer. size_t is the type used by C to
represent object sizes.
> 71 looks like it is returning two somethings
> from the structure definition. Is this a
> function or a structure or both?
Now we get to the typedef part. Here is a declaration that only says
what's in a struct S:
struct S { int a; float b };
After that, I can declare one or two of them:
struct S s, t;
but I could have done both together like this:
struct S { int a; float b } s, t;
And I can also add further decoration to declare some objects with
derived types:
struct S { int a; float b } s, *p, ar[3];
declares a struct S (called s), a pointer (called p) to a struct S and
and array of three struct S objects with the name ar.
Putting typedef in front of a declaration changes the meaning so that
any declared names (like "s" and "p" and "ar" above) become aliases for
their types, rather than variables of that type. Thus
typedef struct S { int a; float b } s, *p, ar[3];
makes "one" an alias for the type "struct S", "p" an alias for "pointer
to a struct S" and "ar" an alias for "array of three struct S".
Obviously, in real life, you would not use such short names for types.
Can you now see what the declaration is doing?
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | T <T@invalid.invalid> |
|---|---|
| Date | 2021-01-18 17:41 -0800 |
| Message-ID | <ru5dbr$6si$1@dont-email.me> |
| In reply to | #158442 |
On 1/18/21 5:37 PM, Ben Bacarisse wrote:
> T <T@invalid.invalid> writes:
>
>> https://gitlab.freedesktop.org/xorg/app/xclipboard/-/blob/master/xclipboard.c
>>
>> 66: typedef struct _Clip {
>> 67: struct _Clip *next, *prev;
>> 68: char *clip;
>> 69: char *filename;
>> 70: size_t avail;
>> 71: } ClipRec, *ClipPtr;
>>
>> Okay now I am confused. What??? Yes, AGAIN!
>>
>> 66 defines a structure called "_Clip". So far
>> so good
>
> It's a little bit more than that. The typedef means that then whole
> declaration will also define some "type names" -- aliases for types.
>
> Putting that aside, yes, struct X { ... } is how a structure is defined.
> The definition says what types of object are contained in an instance of
> the structure. These are called the members.
>
>> 67 look like it is doing it again inside
>> the original definition. Is this a structure
>> embedded in another structure reusing the
>> same name ????
>
> Without the { ... } no structure is being defined. Instead, the type
> "struct _Clip" is used to declare objects -- in this case two members
> called next and prev. But the type of these members is not "struct
> _Clip". It is "pointer to struct _Clip". That's what the * in front of
> the declared name means.
>
> So a struct _Clip contains two pointers to other struct _Clip objects.
> This is clearly going to be a doubly linked list.
>
>> 68 & 69 look like they a declaring pointers to
>> a character. Are not pointers usually
>> int64's?
>
> A pointer a is derived type in C. You can have a pointer to a
> character, a pointer to an int or, as I've just described, a pointer to
> a struct object.
>
>> 70 What is an "avail"? Some kind of structure?
>
> No, it is just an unsigned integer. size_t is the type used by C to
> represent object sizes.
>
>> 71 looks like it is returning two somethings
>> from the structure definition. Is this a
>> function or a structure or both?
>
> Now we get to the typedef part. Here is a declaration that only says
> what's in a struct S:
>
> struct S { int a; float b };
>
> After that, I can declare one or two of them:
>
> struct S s, t;
>
> but I could have done both together like this:
>
> struct S { int a; float b } s, t;
>
> And I can also add further decoration to declare some objects with
> derived types:
>
> struct S { int a; float b } s, *p, ar[3];
>
> declares a struct S (called s), a pointer (called p) to a struct S and
> and array of three struct S objects with the name ar.
>
> Putting typedef in front of a declaration changes the meaning so that
> any declared names (like "s" and "p" and "ar" above) become aliases for
> their types, rather than variables of that type. Thus
>
> typedef struct S { int a; float b } s, *p, ar[3];
>
> makes "one" an alias for the type "struct S", "p" an alias for "pointer
> to a struct S" and "ar" an alias for "array of three struct S".
> Obviously, in real life, you would not use such short names for types.
>
> Can you now see what the declaration is doing?
>
Hi Ben,
I am going to have to read and reread what you wrote
several times before the lights go off. Thank you for
the wonderful write up!
-T
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-19 01:52 +0000 |
| Message-ID | <87bldl66ci.fsf@bsb.me.uk> |
| In reply to | #158443 |
T <T@invalid.invalid> writes:
> On 1/18/21 5:37 PM, Ben Bacarisse wrote:
>> T <T@invalid.invalid> writes:
>>
>>> https://gitlab.freedesktop.org/xorg/app/xclipboard/-/blob/master/xclipboard.c
>>>
>>> 66: typedef struct _Clip {
>>> 67: struct _Clip *next, *prev;
>>> 68: char *clip;
>>> 69: char *filename;
>>> 70: size_t avail;
>>> 71: } ClipRec, *ClipPtr;
>>>
>>> Okay now I am confused. What??? Yes, AGAIN!
>>>
>>> 66 defines a structure called "_Clip". So far
>>> so good
>>
>> It's a little bit more than that. The typedef means that then whole
>> declaration will also define some "type names" -- aliases for types.
>>
>> Putting that aside, yes, struct X { ... } is how a structure is defined.
>> The definition says what types of object are contained in an instance of
>> the structure. These are called the members.
>>
>>> 67 look like it is doing it again inside
>>> the original definition. Is this a structure
>>> embedded in another structure reusing the
>>> same name ????
>>
>> Without the { ... } no structure is being defined. Instead, the type
>> "struct _Clip" is used to declare objects -- in this case two members
>> called next and prev. But the type of these members is not "struct
>> _Clip". It is "pointer to struct _Clip". That's what the * in front of
>> the declared name means.
>>
>> So a struct _Clip contains two pointers to other struct _Clip objects.
>> This is clearly going to be a doubly linked list.
>>
>>> 68 & 69 look like they a declaring pointers to
>>> a character. Are not pointers usually
>>> int64's?
>>
>> A pointer a is derived type in C. You can have a pointer to a
"A pointer type is a derived type in C".
>> character, a pointer to an int or, as I've just described, a pointer to
>> a struct object.
>>
>>> 70 What is an "avail"? Some kind of structure?
>>
>> No, it is just an unsigned integer. size_t is the type used by C to
>> represent object sizes.
>>
>>> 71 looks like it is returning two somethings
>>> from the structure definition. Is this a
>>> function or a structure or both?
>>
>> Now we get to the typedef part. Here is a declaration that only says
>> what's in a struct S:
>>
>> struct S { int a; float b };
>>
>> After that, I can declare one or two of them:
>>
>> struct S s, t;
>>
>> but I could have done both together like this:
>>
>> struct S { int a; float b } s, t;
>>
>> And I can also add further decoration to declare some objects with
>> derived types:
>>
>> struct S { int a; float b } s, *p, ar[3];
>>
>> declares a struct S (called s), a pointer (called p) to a struct S and
>> and array of three struct S objects with the name ar.
>>
>> Putting typedef in front of a declaration changes the meaning so that
>> any declared names (like "s" and "p" and "ar" above) become aliases for
>> their types, rather than variables of that type. Thus
>>
>> typedef struct S { int a; float b } s, *p, ar[3];
>>
>> makes "one" an alias for the type "struct S", "p" an alias for
>> "pointer
Makes "s" an alias for the type "struct S". (I changed the name and
did not edit all occurrences.)
>> to a struct S" and "ar" an alias for "array of three struct S".
>> Obviously, in real life, you would not use such short names for types.
>>
>> Can you now see what the declaration is doing?
>>
>
> Hi Ben,
>
> I am going to have to read and reread what you wrote
> several times before the lights go off. Thank you for
> the wonderful write up!
You're welcome. Since you plan to read it more than once, it seems only
fair to correct a couple of mistakes.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | T <T@invalid.invalid> |
|---|---|
| Date | 2021-01-18 18:03 -0800 |
| Message-ID | <ru5eld$de7$1@dont-email.me> |
| In reply to | #158445 |
On 1/18/21 5:52 PM, Ben Bacarisse wrote:
> T <T@invalid.invalid> writes:
>
>> On 1/18/21 5:37 PM, Ben Bacarisse wrote:
>>> T <T@invalid.invalid> writes:
>>>
>>>> https://gitlab.freedesktop.org/xorg/app/xclipboard/-/blob/master/xclipboard.c
>>>>
>>>> 66: typedef struct _Clip {
>>>> 67: struct _Clip *next, *prev;
>>>> 68: char *clip;
>>>> 69: char *filename;
>>>> 70: size_t avail;
>>>> 71: } ClipRec, *ClipPtr;
>>>>
>>>> Okay now I am confused. What??? Yes, AGAIN!
>>>>
>>>> 66 defines a structure called "_Clip". So far
>>>> so good
>>>
>>> It's a little bit more than that. The typedef means that then whole
>>> declaration will also define some "type names" -- aliases for types.
>>>
>>> Putting that aside, yes, struct X { ... } is how a structure is defined.
>>> The definition says what types of object are contained in an instance of
>>> the structure. These are called the members.
>>>
>>>> 67 look like it is doing it again inside
>>>> the original definition. Is this a structure
>>>> embedded in another structure reusing the
>>>> same name ????
>>>
>>> Without the { ... } no structure is being defined. Instead, the type
>>> "struct _Clip" is used to declare objects -- in this case two members
>>> called next and prev. But the type of these members is not "struct
>>> _Clip". It is "pointer to struct _Clip". That's what the * in front of
>>> the declared name means.
>>>
>>> So a struct _Clip contains two pointers to other struct _Clip objects.
>>> This is clearly going to be a doubly linked list.
>>>
>>>> 68 & 69 look like they a declaring pointers to
>>>> a character. Are not pointers usually
>>>> int64's?
>>>
>>> A pointer a is derived type in C. You can have a pointer to a
>
> "A pointer type is a derived type in C".
>
>>> character, a pointer to an int or, as I've just described, a pointer to
>>> a struct object.
>>>
>>>> 70 What is an "avail"? Some kind of structure?
>>>
>>> No, it is just an unsigned integer. size_t is the type used by C to
>>> represent object sizes.
>>>
>>>> 71 looks like it is returning two somethings
>>>> from the structure definition. Is this a
>>>> function or a structure or both?
>>>
>>> Now we get to the typedef part. Here is a declaration that only says
>>> what's in a struct S:
>>>
>>> struct S { int a; float b };
>>>
>>> After that, I can declare one or two of them:
>>>
>>> struct S s, t;
>>>
>>> but I could have done both together like this:
>>>
>>> struct S { int a; float b } s, t;
>>>
>>> And I can also add further decoration to declare some objects with
>>> derived types:
>>>
>>> struct S { int a; float b } s, *p, ar[3];
>>>
>>> declares a struct S (called s), a pointer (called p) to a struct S and
>>> and array of three struct S objects with the name ar.
>>>
>>> Putting typedef in front of a declaration changes the meaning so that
>>> any declared names (like "s" and "p" and "ar" above) become aliases for
>>> their types, rather than variables of that type. Thus
>>>
>>> typedef struct S { int a; float b } s, *p, ar[3];
>>>
>>> makes "one" an alias for the type "struct S", "p" an alias for
>>> "pointer
>
> Makes "s" an alias for the type "struct S". (I changed the name and
> did not edit all occurrences.)
>
>>> to a struct S" and "ar" an alias for "array of three struct S".
>>> Obviously, in real life, you would not use such short names for types.
>>>
>>> Can you now see what the declaration is doing?
>>>
>>
>> Hi Ben,
>>
>> I am going to have to read and reread what you wrote
>> several times before the lights go off. Thank you for
>> the wonderful write up!
>
> You're welcome. Since you plan to read it more than once, it seems only
> fair to correct a couple of mistakes.
>
You make a mistake???? Tell me it isn't so!!!! NO NO NO NO!!!
I NEVER make mistakes. What??? Okay, sometimes, maybe ...
:-)
Thank for the updates!
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-01-18 19:00 -0800 |
| Message-ID | <ru5i1b$26r$1@dont-email.me> |
| In reply to | #158441 |
On 1/18/2021 5:01 PM, T wrote:
>
> 66: typedef struct _Clip {
> 67: struct _Clip *next, *prev;
> 68: char *clip;
> 69: char *filename;
> 70: size_t avail;
> 71: } ClipRec, *ClipPtr;
>
> Okay now I am confused. What??? Yes, AGAIN!
>
> 66 defines a structure called "_Clip". So far
> so good
No. It defines a struct type called `struct _Clip`. It takes the whole
`struct _Clip` - two words - to name this type in C.
> 67 look like it is doing it again inside
> the original definition. Is this a structure
> embedded in another structure reusing the
> same name ????
No. C has no such thing as "nested" types. `struct _Clip` inside names
exactly the same type as the one being defined: `struct _Clip`. This
struct type contains two pointers to the same struct type.
> 68 & 69 look like they a declaring pointers to
> a character. Are not pointers usually
> int64's?
Pointers are pointers. They are not "int64's".
> 70 What is an "avail"? Some kind of structure?
`size_t` is an unsigned integer type of implementation-defined width.
So, no, it is not a structure. It is simply an integer.
> 71 looks like it is returning two somethings
> from the structure definition. Is this a
> function or a structure or both?
"Returning"? It is not returning anything. This a continuation of what
was started by `typedef` keyword. The newly declared type `struct _Clip`
gets an alias - `ClipRec`. So, now `ClipRec` designates the same type as
`struct _Clip`.
And `ClipPtr` is another alias. It stands for `struct _Clip *`.
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-19 11:34 +0000 |
| Message-ID | <otzNH.315709$9J69.3285@fx21.ams4> |
| In reply to | #158441 |
On 19/01/2021 01:01, T wrote:
> 66: typedef struct _Clip {
> 67: struct _Clip *next, *prev;
> 68: char *clip;
> 69: char *filename;
> 70: size_t avail;
> 71: } ClipRec, *ClipPtr;
See if this is any better; I rewrote it in the syntax my own language uses:
record ClipRec =
ref ClipRec next, prev
ref char clip
ref char filename
u64 avail
end
type ClipPtr = ref ClipRec
'ref' means 'pointer to', and will be a 64-bit pointer on 64-bit systems
'record' is what I call a 'struct'
'u64' is uint64_t, which is what 'size_t' usually is on 64-bit systems
C's 'typedef' is rather peculiar in being able to declare multiple,
modified versions of a type being aliased: C's *ClipPtr is an alias for
'struct _Clip*', but my syntax has no concept of struct tags.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2021-01-19 04:18 -0800 |
| Message-ID | <e941c4f4-ce38-4318-8003-0e67ac533bf7n@googlegroups.com> |
| In reply to | #158455 |
On Tuesday, 19 January 2021 at 11:34:56 UTC, Bart wrote:
> On 19/01/2021 01:01, T wrote:
> > 66: typedef struct _Clip {
> > 67: struct _Clip *next, *prev;
> > 68: char *clip;
> > 69: char *filename;
> > 70: size_t avail;
> > 71: } ClipRec, *ClipPtr;
> See if this is any better; I rewrote it in the syntax my own language uses:
>
> record ClipRec =
> ref ClipRec next, prev
> ref char clip
> ref char filename
> u64 avail
> end
>
"next" and "prev" point to single instances of the structure.
"filename" points to a whole string of chars.
That's confusing, but it's C, and almost everyone either knows C or needs to
learn it, if they live in the world of low-level compiled programming at all.
Your language has the same problem. But the difference is that few people
know it, and few people who learn it will use it for much. So the potential
for confusion is a lot worse than with C. Particularly because "ref" is obviously
short for "reference", and in C++ a reference is partly an attempt to avoid this
ambiguity in C pointers by restricting the reference to one object.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-19 13:01 +0000 |
| Message-ID | <ZKANH.151478$yaRe.111860@fx07.ams4> |
| In reply to | #158456 |
On 19/01/2021 12:18, Malcolm McLean wrote:
> On Tuesday, 19 January 2021 at 11:34:56 UTC, Bart wrote:
>> On 19/01/2021 01:01, T wrote:
>>> 66: typedef struct _Clip {
>>> 67: struct _Clip *next, *prev;
>>> 68: char *clip;
>>> 69: char *filename;
>>> 70: size_t avail;
>>> 71: } ClipRec, *ClipPtr;
>> See if this is any better; I rewrote it in the syntax my own language uses:
>>
>> record ClipRec =
>> ref ClipRec next, prev
>> ref char clip
>> ref char filename
>> u64 avail
>> end
>>
> "next" and "prev" point to single instances of the structure.
> "filename" points to a whole string of chars.
>
> That's confusing, but it's C, and almost everyone either knows C or needs to
> learn it, if they live in the world of low-level compiled programming at all.
>
> Your language has the same problem. But the difference is that few people
> know it, and few people who learn it will use it for much. So the potential
> for confusion is a lot worse than with C. Particularly because "ref" is obviously
> short for "reference", and in C++ a reference is partly an attempt to avoid this
> ambiguity in C pointers by restricting the reference to one object.
>
'ref' comes from Algol68, which came out a few years before C.
For 'ref char' I normally write the internal alias 'ichar', but I wrote
'ref char' here as it's closer to the C. (My 'char' however is unsigned.)
Both pointer types can have offsets applied and can be stepped, like C.
But to apply an offset you need an actual offset, like (P+offset)^, or
*(P+offset) in C.
What you CAN'T do is pretend they are arrays and do P[offset] (or
usually the more misleading P[i]) as in C.
And what you CAN do is use actual arrays in a way that is unacceptable
in C or not possible:
proc fn1(ref[]T A) # pointer to array, access as A^[i] or A[i]
proc fn2([]T &A) # pass by reference, access as A[i]
proc fn3(ref T A) # pass a pointer, access as (A+i)^
proc fn4([n]T A) # pass array, access as A[i]
proc fn5(slice[]T A) # pass slice, access as A[i], A.len etc
In C:
void fn1(T (*A)) # access as (*A)[i]
void fn2 ... # not available (will be in C++)
void fn3(T* A) # access as A[i] (!) or as *(A+i)^
void fn4 ... # not available
void fn5 ... # not available
Remember however that T's threads are about interfacing to C APIs
therefore they need to be able to duplicate the exact layout of a C
struct, and to have close-enough field types. If used opaqualy, those
pointers might as well just be u64 types.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-19 21:39 +0000 |
| Message-ID | <87zh144nem.fsf@bsb.me.uk> |
| In reply to | #158457 |
Bart <bc@freeuk.com> writes:
> On 19/01/2021 12:18, Malcolm McLean wrote:
>> On Tuesday, 19 January 2021 at 11:34:56 UTC, Bart wrote:
>>> On 19/01/2021 01:01, T wrote:
>>>> 66: typedef struct _Clip {
>>>> 67: struct _Clip *next, *prev;
>>>> 68: char *clip;
>>>> 69: char *filename;
>>>> 70: size_t avail;
>>>> 71: } ClipRec, *ClipPtr;
>>> See if this is any better; I rewrote it in the syntax my own language uses:
>>>
>>> record ClipRec =
>>> ref ClipRec next, prev
>>> ref char clip
>>> ref char filename
>>> u64 avail
>>> end
>>>
>> "next" and "prev" point to single instances of the structure.
>> "filename" points to a whole string of chars.
>>
>> That's confusing, but it's C, and almost everyone either knows C or needs to
>> learn it, if they live in the world of low-level compiled programming at all.
>>
>> Your language has the same problem. But the difference is that few people
>> know it, and few people who learn it will use it for much. So the potential
>> for confusion is a lot worse than with C. Particularly because "ref" is obviously
>> short for "reference", and in C++ a reference is partly an attempt to avoid this
>> ambiguity in C pointers by restricting the reference to one object.
>
> 'ref' comes from Algol68, which came out a few years before C.
But with a different meaning. You seem to use it to mean pointer --
much more like C's * than Algol 68's ref.
> Both pointer types can have offsets applied and can be stepped, like
> C. But to apply an offset you need an actual offset, like (P+offset)^,
> or *(P+offset) in C.
>
> What you CAN'T do is pretend they are arrays and do P[offset] (or
> usually the more misleading P[i]) as in C.
Seems odd. I don't see the problem in offering a shortcut for accessing
consecutive objects of the pointed-to type. I'd go one way or the other
-- prohibit access using pointer arithmetic, or make using it simple.
And of course C does not "pretend" that a pointer is an array, it
provides a shortcut for some pointer manipulation because there is no
other kind of array access.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-19 23:20 +0000 |
| Message-ID | <yPJNH.233574$JT57.132182@fx31.ams4> |
| In reply to | #158466 |
On 19/01/2021 21:39, Ben Bacarisse wrote: > Bart <bc@freeuk.com> writes: >> 'ref' comes from Algol68, which came out a few years before C. > > But with a different meaning. You seem to use it to mean pointer -- > much more like C's * than Algol 68's ref. How different? AFAIK as they both add an extra level of indirection to a type. (My version had to be simpler because it ran on and for 8-bit machines.) >> Both pointer types can have offsets applied and can be stepped, like >> C. But to apply an offset you need an actual offset, like (P+offset)^, >> or *(P+offset) in C. >> >> What you CAN'T do is pretend they are arrays and do P[offset] (or >> usually the more misleading P[i]) as in C. > > Seems odd. I don't see the problem in offering a shortcut for accessing > consecutive objects of the pointed-to type. The problem is that it has influenced the whole way that C code is written, with arrays of T nearly always passed by a T* type rather than (*T)[]. Because ANY type that starts with 'pointer to' can be dereferenced or indexed, the language can't determine when that is done inappropriately. Sure, it sometimes can be very convenient (especially so when working with slices), but I think that is not worth the loss of type safety. > I'd go one way or the other > -- prohibit access using pointer arithmetic, or make using it simple. > And of course C does not "pretend" that a pointer is an array, it > provides a shortcut for some pointer manipulation because there is no > other kind of array access. By /requiring/ pointer arithmetic to use *(p+i) rather than p[i], then you will know pointer manipulations are going on, something a little lower level and cruder than array indexing, and possibly underhand.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-20 00:25 +0000 |
| Message-ID | <874kjc4fq2.fsf@bsb.me.uk> |
| In reply to | #158471 |
Bart <bc@freeuk.com> writes: > On 19/01/2021 21:39, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: > >>> 'ref' comes from Algol68, which came out a few years before C. >> >> But with a different meaning. You seem to use it to mean pointer -- >> much more like C's * than Algol 68's ref. > > How different? AFAIK as they both add an extra level of indirection to > a type. REF does not denote a pointer. If it was anything even close to being like a pointer, variables of mode T would not have mode REF T. Your usage appears to map to C's use of * almost exactly. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-20 12:42 +0000 |
| Message-ID | <GyVNH.404316$ca39.77514@fx28.ams4> |
| In reply to | #158472 |
On 20/01/2021 00:25, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 19/01/2021 21:39, Ben Bacarisse wrote:
>>> Bart <bc@freeuk.com> writes:
>>
>>>> 'ref' comes from Algol68, which came out a few years before C.
>>>
>>> But with a different meaning. You seem to use it to mean pointer --
>>> much more like C's * than Algol 68's ref.
>>
>> How different? AFAIK as they both add an extra level of indirection to
>> a type.
>
> REF does not denote a pointer. If it was anything even close to being
> like a pointer, variables of mode T would not have mode REF T. Your
> usage appears to map to C's use of * almost exactly.
There was a long discussion about this in comp.lang.misc last year that
I don't wish to repeat, however consider this table:
C type Algol68 mode
enum {A=0}; int INT (decl will be INT A=0;)
int B; int REF INT
int* C; int* REF REF INT
int** D; int** REF REF REF INT
For the variables, Algol68 has one more REF than the corresponding
number of * of the C type.
This sort of makes sense since B, being a variable, has an extra level
of indirection than A, which is a pure value with no storage.
In C, both A and B have the same type, this is because variables, in
common with virtually every HLL, have an auto-deref applied in order to
access the value in memory, but it will only ever do one deref.
In Algol68, it will apply derefs as needed according to the context in
which it is used. So if D is used where an Int type is needed, 3 lots of
derefs are applied, two more than in C.
To my mind this added an unacceptable level of confusion, since B has
mode REF INT yet will be used in most places as INT. (And what does the
comparison C = C mean, does it compare int* or int?)
The way I do it, and the way C does it, there /is/ a discrepancy between
ordinary variables, and named constants, since they both have the same
type, but I feel this is well understood, and the language will prohibit
some operations that attempt to treat them equally:
&A Not allowed
&B OK, yields int*
A=1 Not allowed
B=1 OK
To summarise, yes, my REF is very close to what * does in C, except that
I segregate pointers and arrays much more rigidly.
(I did at one time have a feature where I could control the number of
auto-derefs done, so here:
int E
ref int F
ref. int G
with G, when used in an expression, it would apply auto-derefs up to the
dot, so it could be used as though it was declared like E. With means
that E /could/ be treated as though it had been declared like this:
ref. int E
Now, variables can have the same extra REF that Algol 68 has!)
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-20 17:39 +0000 |
| Message-ID | <87turb33tj.fsf@bsb.me.uk> |
| In reply to | #158477 |
Bart <bc@freeuk.com> writes:
> On 20/01/2021 00:25, Ben Bacarisse wrote:
>> Bart <bc@freeuk.com> writes:
>>
>>> On 19/01/2021 21:39, Ben Bacarisse wrote:
>>>> Bart <bc@freeuk.com> writes:
>>>
>>>>> 'ref' comes from Algol68, which came out a few years before C.
>>>>
>>>> But with a different meaning. You seem to use it to mean pointer --
>>>> much more like C's * than Algol 68's ref.
>>>
>>> How different? AFAIK as they both add an extra level of indirection to
>>> a type.
>>
>> REF does not denote a pointer. If it was anything even close to being
>> like a pointer, variables of mode T would not have mode REF T. Your
>> usage appears to map to C's use of * almost exactly.
>
> There was a long discussion about this in comp.lang.misc last year
> that I don't wish to repeat, however consider this table:
>
> C type Algol68 mode
>
> enum {A=0}; int INT (decl will be INT A=0;)
> int B; int REF INT
> int* C; int* REF REF INT
> int** D; int** REF REF REF INT
>
> For the variables, Algol68 has one more REF than the corresponding
> number of * of the C type.
I know both Algol 68 and C quite well. I don't see the point in going
over the similarities and differences. REFs in Algol 68 are not
pointers, but ref in yours are (so far as I can tell). You use them
almost exactly as in C whereas REF REF types do not behave like C
pointers (and your refs) in all bit the very simplest cases. The
biggest difference being that, since your refs are just pointers, you
can do arithmetic with them.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-20 19:32 +0000 |
| Message-ID | <gz%NH.428083$bG69.38447@fx23.ams4> |
| In reply to | #158492 |
On 20/01/2021 17:39, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> There was a long discussion about this in comp.lang.misc last year
>> that I don't wish to repeat, however consider this table:
>>
>> C type Algol68 mode
>>
>> enum {A=0}; int INT (decl will be INT A=0;)
>> int B; int REF INT
>> int* C; int* REF REF INT
>> int** D; int** REF REF REF INT
>>
>> For the variables, Algol68 has one more REF than the corresponding
>> number of * of the C type.
>
> I know both Algol 68 and C quite well. I don't see the point in going
> over the similarities and differences. REFs in Algol 68 are not
> pointers, but ref in yours are (so far as I can tell). You use them
> almost exactly as in C whereas REF REF types do not behave like C
> pointers (and your refs) in all bit the very simplest cases. The
> biggest difference being that, since your refs are just pointers, you
> can do arithmetic with them.
>
You might remember that Algol 68 was perceived as being 'difficult',
backed up by complex ideas.
My job was to take the parts I liked, such as the syntax, especially for
type denotations, and use that as the basis for a simple systems language.
Since I could never figure out exactly what any bit of Algol68 was
supposed to do, I had to provide simpler, more obvious semantics.
I would say however that Algol68 REFs /are/ pointers, they just work
differently with little if any explicit dereferencing (eg. you write
either C=C from my above example, or C is C, depending on your
intentions, whereas C (the language) would use *C==*C or C==C).
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-20 20:45 +0000 |
| Message-ID | <87im7r2v7u.fsf@bsb.me.uk> |
| In reply to | #158503 |
Bart <bc@freeuk.com> writes:
> On 20/01/2021 17:39, Ben Bacarisse wrote:
>> Bart <bc@freeuk.com> writes:
>>
>
>>> There was a long discussion about this in comp.lang.misc last year
>>> that I don't wish to repeat, however consider this table:
>>>
>>> C type Algol68 mode
>>>
>>> enum {A=0}; int INT (decl will be INT A=0;)
>>> int B; int REF INT
>>> int* C; int* REF REF INT
>>> int** D; int** REF REF REF INT
>>>
>>> For the variables, Algol68 has one more REF than the corresponding
>>> number of * of the C type.
>>
>> I know both Algol 68 and C quite well. I don't see the point in going
>> over the similarities and differences. REFs in Algol 68 are not
>> pointers, but ref in yours are (so far as I can tell). You use them
>> almost exactly as in C whereas REF REF types do not behave like C
>> pointers (and your refs) in all bit the very simplest cases. The
>> biggest difference being that, since your refs are just pointers, you
>> can do arithmetic with them.
>
> You might remember that Algol 68 was perceived as being 'difficult',
> backed up by complex ideas.
The way the grammar was specified was considered difficult and turned
out to be something of a flop. I don't think the actual language was
considered difficult.
> My job was to take the parts I liked, such as the syntax, especially
> for type denotations, and use that as the basis for a simple systems
> language.
>
> Since I could never figure out exactly what any bit of Algol68 was
> supposed to do, I had to provide simpler, more obvious semantics.
i.e. different semantics. As I said, your ref is not so much like Algol
68's REF as it is like C's *. Your ref is almost exactly C's *.
> I would say however that Algol68 REFs /are/ pointers,
That would just confuse people. It doesn't matter, because no one here
is going to learn Algol 68 anytime soon, but you do this with C as all.
You paint C as more complex than it really is because you insist on
using incorrect descriptions.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-21 16:12 +0000 |
| Message-ID | <WJhOH.1799806$ckra.1797686@fx37.ams4> |
| In reply to | #158505 |
On 20/01/2021 20:45, Ben Bacarisse wrote: > Bart <bc@freeuk.com> writes: >> You might remember that Algol 68 was perceived as being 'difficult', >> backed up by complex ideas. > > The way the grammar was specified was considered difficult and turned > out to be something of a flop. I don't think the actual language was > considered difficult. The syntax itself wasn't that hard as a finished result, if you avoided the special grammar they tried to use. But for me the difficulty was in not having high enough confidence in knowing exactly was going on in a bit of code, not helped by all those implicit conversions (rowing, proceduring etc). > >> My job was to take the parts I liked, such as the syntax, especially >> for type denotations, and use that as the basis for a simple systems >> language. >> >> Since I could never figure out exactly what any bit of Algol68 was >> supposed to do, I had to provide simpler, more obvious semantics. > > i.e. different semantics. As I said, your ref is not so much like Algol > 68's REF as it is like C's *. Your ref is almost exactly C's *. Probably. This would have been over 10 years before I had any dealings with C. Apart from ASM, my experience with pointers had been with Pascal. Remember this is for a systems language. >> I would say however that Algol68 REFs /are/ pointers, > > That would just confuse people. Look at what REFs are used for (outside of their being needed in that language to implement variables); that role will done by pointers in languages only having raw pointers. It doesn't matter, because no one here > is going to learn Algol 68 anytime soon, but you do this with C as all. > You paint C as more complex than it really is because you insist on > using incorrect descriptions. > C makes nearly everything more complicated than it need be: * Type declarations * Line continuation (see that other thread) * Pointless extra namespaces (tags and labels) * Index arrays OR pointers * Extern names that are also exported ... * ... and in general, allowing multiple declarations of the same name outside of functions, with special rules as to whether disimilar types and attributes are compatible or not * Structs with or without a tag, with or without a typedef name, declared separately or in situ (C will allow most of those 8 combinations; I allow exactly one) * Nested header files (I mean, includes used in place of an import feature), with arbitrary combinations of absolute and relative file paths at each level * /Needing/ some subset of 29 standard headers in every module, for the most basic language features * 20-28 different ways of specifying a 64-bit int (the extra 8 are when long is the same size as long long), not including an infinite number of ways of applying 'const' * Print format codes (especially when using int64_t etc) * Having to use scanf to read user input * The rules that determine whether the result of a binary op with two integer types are signed or unsigned etc etc I think you would claim this stuff isn't complicated because with each one, you can explain exactly why it is so. I say it is complicated because it is unnecessary. People have enough trouble learning C.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-21 17:10 +0000 |
| Message-ID | <87k0s61ajb.fsf@bsb.me.uk> |
| In reply to | #158522 |
Bart <bc@freeuk.com> writes: <about confusing descriptions> >> It doesn't matter, because no one here >> is going to learn Algol 68 anytime soon, but you do this with C as all. >> You paint C as more complex than it really is because you insist on >> using incorrect descriptions. > > C makes nearly everything more complicated than it need be: My point was that you appear intent on making it worse. C is what it is. You can (and do) gripe about it, but it won't change. You, however, could change how you explain it. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2021-01-21 11:51 -0800 |
| Message-ID | <aa190912-9de0-4119-9f1f-3a2ea25b32f5n@googlegroups.com> |
| In reply to | #158523 |
On Thursday, 21 January 2021 at 17:10:12 UTC, Ben Bacarisse wrote: > Bart <b...@freeuk.com> writes: > > <about confusing descriptions> > >> It doesn't matter, because no one here > >> is going to learn Algol 68 anytime soon, but you do this with C as all. > >> You paint C as more complex than it really is because you insist on > >> using incorrect descriptions. > > > > C makes nearly everything more complicated than it need be: > My point was that you appear intent on making it worse. C is what it > is. You can (and do) gripe about it, but it won't change. You, > however, could change how you explain it. > One way to respond to C's flaws is to design your own language which doesn't suffer from the same drawbacks. But then you'll want to promote it. So naturally you then emphasise the flaws that you see in C.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-22 12:26 +0000 |
| Message-ID | <fwzOH.1181171$W6Df.22607@fx12.ams4> |
| In reply to | #158526 |
On 21/01/2021 19:51, Malcolm McLean wrote:
> On Thursday, 21 January 2021 at 17:10:12 UTC, Ben Bacarisse wrote:
>> Bart <b...@freeuk.com> writes:
>>
>> <about confusing descriptions>
>>>> It doesn't matter, because no one here
>>>> is going to learn Algol 68 anytime soon, but you do this with C as all.
>>>> You paint C as more complex than it really is because you insist on
>>>> using incorrect descriptions.
>>>
>>> C makes nearly everything more complicated than it need be:
>> My point was that you appear intent on making it worse. C is what it
>> is. You can (and do) gripe about it, but it won't change. You,
>> however, could change how you explain it.
>>
> One way to respond to C's flaws is to design your own language which
> doesn't suffer from the same drawbacks. But then you'll want to promote
> it. So naturally you then emphasise the flaws that you see in C.
>
I was using my own languages many years before I used C. Then I wanted
to give up my languages, which came with the headache of maintaining
them, and switch to C. Also I had in mind getting a job.
But I just couldn't do it.
By drawing attention to the problems I'd half-hoped someone else would
devise an alternative I could use, but they're mostly worse!
If they solve some problems with C, they add many of their own. They are
also bigger, slower, and more complicated.
One of the worst is Zig. I tried to write this simple BASIC program in
it (actually this was the first program I ever saw in action):
10 for i=1 to 20
20 print i, sqr(i)
30 next i
In Zig it's this; note that Zig doesn't have for-loops that iterate over
a range:
const std = @import("std");
pub fn main() !void {
var i:i32 = 0;
i=1;
while (i<=10) {
std.debug.print("{} {}\n", .{i, @sqrt(@intToFloat(f64,i))});
i = i+1;
}
}
This is actually one of the shorter versions. Other problems with this,
not apparent here, is that (1) Zig doesn't like hard tabs - you have to
expand to spaces; (2) Zig didn't like CRLF newlines, even on Windows;
you had to convert to LF. But recent versions do accept them.
But just take a look at that print statement! While it doesn't need C's
format codes, it uses twice the number of tokens as C:
printf("%d %f\n", i, sqrt(i));
My syntax can express it like this:
println i, sqrt i
Two tokens fewer than 1970s BASIC, if I omit the parentheses.
This is why I persevere. I'm not interested in promoting it however,
that would be even more of a headache than maintaining it for my own use.
(Like someone who cooks their own delicious recipes may not be
interested in getting into large scale production!)
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web