Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Help! I'm trapped in a Chinese computer factory!


devel / comp.lang.c / Re: Distinction between identical struct types

SubjectAuthor
* Distinction between identical struct typesThiago Adams
+* Re: Distinction between identical struct typesBart
|`* Re: Distinction between identical struct typesThiago Adams
| `* Re: Distinction between identical struct typesBart
|  +* Re: Distinction between identical struct typesThiago Adams
|  |`- Re: Distinction between identical struct typesBart
|  `- Re: Distinction between identical struct typesluser droog
+- Re: Distinction between identical struct typesStefan Ram
+- Re: Distinction between identical struct typesAndrey Tarasevich
+- Re: Distinction between identical struct typesMalcolm McLean
+- Re: Distinction between identical struct typesjames...@alumni.caltech.edu
`* Re: Distinction between identical struct typesRichard Damon
 `- Re: Distinction between identical struct typesThiago Adams

1
Distinction between identical struct types

<01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17404&group=comp.lang.c#17404

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a0c:ff01:: with SMTP id w1mr10704690qvt.28.1625920860487;
Sat, 10 Jul 2021 05:41:00 -0700 (PDT)
X-Received: by 2002:a05:6214:224c:: with SMTP id c12mr41264593qvc.7.1625920860248;
Sat, 10 Jul 2021 05:41:00 -0700 (PDT)
Path: i2pn2.org!i2pn.org!paganini.bofh.team!news.dns-netz.com!news.freedyn.net!newsfeed.xs4all.nl!newsfeed7.news.xs4all.nl!feeder1.cambriumusenet.nl!feed.tweak.nl!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Sat, 10 Jul 2021 05:41:00 -0700 (PDT)
Injection-Info: google-groups.googlegroups.com; posting-host=189.6.254.153; posting-account=xFcAQAoAAAAoWlfpQ6Hz2n-MU9fthxbY
NNTP-Posting-Host: 189.6.254.153
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Subject: Distinction between identical struct types
From: thiago.a...@gmail.com (Thiago Adams)
Injection-Date: Sat, 10 Jul 2021 12:41:00 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Thiago Adams - Sat, 10 Jul 2021 12:41 UTC

Does anyone know or can see a reason why the C language makes
distinction between identical struct types?

Like this:

void F(struct {int i; }* p){}

int main() {
struct { int i; } s;
F(&s);
}

Compare with functions:

void F(void (*pf)(void)){}
void F2(void) {}
int main()
{ void (*pf)(void) = F2;
F(pf);
}

Must be something with padding?
But why, we are inside the same compiler?
How safe we are doing a cast?

Re: Distinction between identical struct types

<scc5ig$i8o$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17405&group=comp.lang.c#17405

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: Sat, 10 Jul 2021 13:58:53 +0100
Organization: A noiseless patient Spider
Lines: 36
Message-ID: <scc5ig$i8o$1@dont-email.me>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 12:58:56 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="18712"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+GBjfk+Z2bv8qJbNKONlZxncz3km4LuEk="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:r1d4B5wf7CqqOOPW1ll8RRaLPgc=
In-Reply-To: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210709-8, 9/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 12:58 UTC

On 10/07/2021 13:41, Thiago Adams wrote:
> Does anyone know or can see a reason why the C language makes
> distinction between identical struct types?
>
> Like this:
>
> void F(struct {int i; }* p){}
>
> int main() {
> struct { int i; } s;
> F(&s);
> }
>
> Compare with functions:
>
> void F(void (*pf)(void)){}
> void F2(void) {}
> int main()
> {
> void (*pf)(void) = F2;
> F(pf);
> }
>
> Must be something with padding?
> But why, we are inside the same compiler?
> How safe we are doing a cast?
>
>

What's the algorithm for determining whether two structs are compatible?

It would need to deal with differently named fields, locally defined
types, local values of pack(), anonymous unions etc.

However, some want to use structs in order to enforce type protection
especially when the contents have an identical layout.

Re: Distinction between identical struct types

<dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17410&group=comp.lang.c#17410

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a05:6214:1303:: with SMTP id a3mr21476503qvv.49.1625930079601; Sat, 10 Jul 2021 08:14:39 -0700 (PDT)
X-Received: by 2002:ae9:de47:: with SMTP id s68mr43212925qkf.39.1625930079334; Sat, 10 Jul 2021 08:14:39 -0700 (PDT)
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!tr1.eu1.usenetexpress.com!feeder.usenetexpress.com!tr2.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Sat, 10 Jul 2021 08:14:39 -0700 (PDT)
In-Reply-To: <scc5ig$i8o$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=189.6.254.153; posting-account=xFcAQAoAAAAoWlfpQ6Hz2n-MU9fthxbY
NNTP-Posting-Host: 189.6.254.153
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com> <scc5ig$i8o$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
Subject: Re: Distinction between identical struct types
From: thiago.a...@gmail.com (Thiago Adams)
Injection-Date: Sat, 10 Jul 2021 15:14:39 +0000
Content-Type: text/plain; charset="UTF-8"
Lines: 87
 by: Thiago Adams - Sat, 10 Jul 2021 15:14 UTC

On Saturday, July 10, 2021 at 9:59:08 AM UTC-3, Bart wrote:
> On 10/07/2021 13:41, Thiago Adams wrote:
> > Does anyone know or can see a reason why the C language makes
> > distinction between identical struct types?
> >
> > Like this:
> >
> > void F(struct {int i; }* p){}
> >
> > int main() {
> > struct { int i; } s;
> > F(&s);
> > }
> >
> > Compare with functions:
> >
> > void F(void (*pf)(void)){}
> > void F2(void) {}
> > int main()
> > {
> > void (*pf)(void) = F2;
> > F(pf);
> > }
> >
> > Must be something with padding?
> > But why, we are inside the same compiler?
> > How safe we are doing a cast?
> >
> >
> What's the algorithm for determining whether two structs are compatible?
Ignore all spaces for instance and compare attributes. In this case the type,
name and order of the members must match.
> It would need to deal with differently named fields, locally defined
> types, local values of pack(), anonymous unions etc.

One justification could possible be just because this is simple to do?
> However, some want to use structs in order to enforce type protection
> especially when the contents have an identical layout.

This justification maybe is applied to typedefs? Using typedefs different types
are compatible if they have the same layout (underline type). (like BOOL and int)

I did some samples with enums:

enum {A, B} F(void) { return A;}
enum {A, B} F2(void) { return B; }

compilers generates an error of redefinition for the enum.

This is fine:

enum {A, B} F(void) {
return B;
}

int main(){
if (F() == A) { }
}

But this is an error:

void F(enum {A, B} e) {}
int main() {
F(A);
}

and this
void F(enum {A, B} e) {}
void F2(enum {A, B} e) {}
is a warning

This is just curiosity.

In other topics I already said that this could be useful
to create parametrized structs using macros.

for instance:
void F(dynamic_array(int)* a){}

Maybe the word extern could be used to create this feature
without breaking compatibly.

void F(extern struct { int* data; int size, capacity; } * a){
}

Re: Distinction between identical struct types

<sccff6$4j8$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17416&group=comp.lang.c#17416

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: Sat, 10 Jul 2021 16:47:47 +0100
Organization: A noiseless patient Spider
Lines: 131
Message-ID: <sccff6$4j8$1@dont-email.me>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
<scc5ig$i8o$1@dont-email.me>
<dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 15:47:51 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="4712"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/YmV8dXWoetjaJx45KrV4FszfZFN1MgDI="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:pv4sR0J9aeaMAOIFfKYPA519/z4=
In-Reply-To: <dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210710-2, 10/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 15:47 UTC

On 10/07/2021 16:14, Thiago Adams wrote:
> On Saturday, July 10, 2021 at 9:59:08 AM UTC-3, Bart wrote:
>> On 10/07/2021 13:41, Thiago Adams wrote:
>>> Does anyone know or can see a reason why the C language makes
>>> distinction between identical struct types?
>>>
>>> Like this:
>>>
>>> void F(struct {int i; }* p){}
>>>
>>> int main() {
>>> struct { int i; } s;
>>> F(&s);
>>> }
>>>
>>> Compare with functions:
>>>
>>> void F(void (*pf)(void)){}
>>> void F2(void) {}
>>> int main()
>>> {
>>> void (*pf)(void) = F2;
>>> F(pf);
>>> }
>>>
>>> Must be something with padding?
>>> But why, we are inside the same compiler?
>>> How safe we are doing a cast?
>>>
>>>
>> What's the algorithm for determining whether two structs are compatible?

> Ignore all spaces for instance and compare attributes. In this case the type,
> name and order of the members must match.

Are you talking about comparing /source code/?

Anyway it's debatable whether member names must match. For the purposes
of copying struct A to struct B, only layout and types need to match.

Member names are only important when accessing members by name:

struct A {int x;} i;
struct B {int y;} j;

struct A* p;

p = &j; // should this be allowed?
p -> y; // but this can't be

>> It would need to deal with differently named fields, locally defined
>> types, local values of pack(), anonymous unions etc.
> One justification could possible be just because this is simple to do?

I haven't tried so don't know all the pitfalls. It would be a recursive
process that needs to deal with nested structs, also with pointers to
structs that may be compatible.

>> However, some want to use structs in order to enforce type protection
>> especially when the contents have an identical layout.
>
> This justification maybe is applied to typedefs?

In C, a typedef does not create a distinct type.

> Using typedefs different types
> are compatible if they have the same layout (underline type). (like BOOL and int)
>
> I did some samples with enums:
>
> enum {A, B} F(void) { return A;}
> enum {A, B} F2(void) { return B; }
>
> compilers generates an error of redefinition for the enum.

Because A and B exist in the same namespace as normal identifiers, so
here they clash.

> This is fine:
>
> enum {A, B} F(void) {
> return B;
> }
>
> int main(){
> if (F() == A) { }
> }
>
> But this is an error:
>
> void F(enum {A, B} e) {}
> int main() {
> F(A);
> }

Because A exists only in the scope of F.

> and this
> void F(enum {A, B} e) {}
> void F2(enum {A, B} e) {}
> is a warning

I guess this is the same warning you would have got in the last example?
(As well as the error due to undefined A.)

> This is just curiosity.
>
> In other topics I already said that this could be useful
> to create parametrized structs using macros.
>
> for instance:
> void F(dynamic_array(int)* a){}
>
> Maybe the word extern could be used to create this feature
> without breaking compatibly.
>
> void F(extern struct { int* data; int size, capacity; } * a){
> }
>

Personally I don't like in-place struct definitions at all.

Define user types by themselves. Then use the new type in variable and
parameter lists.

In any case, if a struct is to be shared, you only really want one
definition of it, in a place where it visible to all code that will use it.

Re: Distinction between identical struct types

<struct-20210710171439@ram.dialup.fu-berlin.de>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17418&group=comp.lang.c#17418

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!news.szaf.org!fu-berlin.de!uni-berlin.de!not-for-mail
From: ram...@zedat.fu-berlin.de (Stefan Ram)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: 10 Jul 2021 16:15:02 GMT
Organization: Stefan Ram
Lines: 14
Expires: 1 Dec 2021 11:59:58 GMT
Message-ID: <struct-20210710171439@ram.dialup.fu-berlin.de>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de 2xYt/pyhJNbRmV9qc4FQBA3nDdwJLCo1Ju0pXrqE9gGlWW
X-Copyright: (C) Copyright 2021 Stefan Ram. All rights reserved.
Distribution through any means other than regular usenet
channels is forbidden. It is forbidden to publish this
article in the Web, to change URIs of this article into links,
and to transfer the body without this notice, but quotations
of parts in other Usenet posts are allowed.
X-No-Archive: Yes
Archive: no
X-No-Archive-Readme: "X-No-Archive" is set, because this prevents some
services to mirror the article in the web. But the article may
be kept on a Usenet archive server with only NNTP access.
X-No-Html: yes
Content-Language: en-US
Accept-Language: de-DE, en-US, it, fr-FR
 by: Stefan Ram - Sat, 10 Jul 2021 16:15 UTC

Thiago Adams <thiago.adams@gmail.com> writes:
>void F(struct {int i; }* p){}
....
> struct { int i; } s;

The presence of a struct-declaration-list in a
struct-or-union-specifier declares a new type,
within a translation unit.

This enables a programmer to specify different
struct types with the same layout but different
semantics.

Re: Distinction between identical struct types

<902be7e1-21af-5fa2-3dec-27dc6c9e8793@gmail.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17428&group=comp.lang.c#17428

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: thiago.a...@gmail.com (Thiago Adams)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: Sat, 10 Jul 2021 16:28:04 -0300
Organization: A noiseless patient Spider
Lines: 177
Message-ID: <902be7e1-21af-5fa2-3dec-27dc6c9e8793@gmail.com>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
<scc5ig$i8o$1@dont-email.me>
<dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
<sccff6$4j8$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Info: reader02.eternal-september.org; posting-host="6c22ddb08540ac1b7c0f14cc39f0cb39";
logging-data="28132"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Tu9cRlixw232w05tr64JXs8XT+7/B7AM="
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101
Firefox/60.0 SeaMonkey/2.53.6
Cancel-Lock: sha1:0nUocMtCBvKFyujJhdCceX0n90Q=
In-Reply-To: <sccff6$4j8$1@dont-email.me>
 by: Thiago Adams - Sat, 10 Jul 2021 19:28 UTC

Bart wrote:
> On 10/07/2021 16:14, Thiago Adams wrote:
>> On Saturday, July 10, 2021 at 9:59:08 AM UTC-3, Bart wrote:
>>> On 10/07/2021 13:41, Thiago Adams wrote:
>>>> Does anyone know or can see a reason why the C language makes
>>>> distinction between identical struct types?
>>>>
>>>> Like this:
>>>>
>>>> void F(struct {int i; }* p){}
>>>>
>>>> int main() {
>>>> struct { int i; } s;
>>>> F(&s);
>>>> }
>>>>
>>>> Compare with functions:
>>>>
>>>> void F(void (*pf)(void)){}
>>>> void F2(void) {}
>>>> int main()
>>>> {
>>>> void (*pf)(void) = F2;
>>>> F(pf);
>>>> }
>>>>
>>>> Must be something with padding?
>>>> But why, we are inside the same compiler?
>>>> How safe we are doing a cast?
>>>>
>>>>
>>> What's the algorithm for determining whether two structs are compatible?
>
>> Ignore all spaces for instance and compare attributes. In this case
>> the type,
>> name and order of the members must match.
>
>
> Are you talking about comparing /source code/?

Not exactly. Let's say some pragma affects the struct layout.
The compiler has it own way to compare internally.

> Anyway it's debatable whether member names must match. For the purposes
> of copying struct A to struct B, only layout and types need to match.
>
> Member names are only important when accessing members by name:
>
>     struct A {int x;} i;
>     struct B {int y;} j;
>
>     struct A* p;
>
>     p = &j;         // should this be allowed?
>     p -> y;         // but this can't be
>
>>> It would need to deal with differently named fields, locally defined
>>> types, local values of pack(), anonymous unions etc.
>> One justification could possible be just because this is simple to do?
>
> I haven't tried so don't know all the pitfalls. It would be a recursive
> process that needs to deal with nested structs, also with pointers to
> structs that may be compatible.

Sorry I wasn't clear..I mean some decisions made for the C language may
be because they are the easiest way to implement. So maybe avoiding
this extra check for struct layout is the easiest/fastest way.

>>> However, some want to use structs in order to enforce type protection
>>> especially when the contents have an identical layout.
>>
>> This justification maybe is applied to typedefs?
>
> In C, a typedef does not create a distinct type.
>
>> Using typedefs different types
>> are compatible if they have the same layout (underline type). (like
>> BOOL and int)

Using the same reasoning of the easiest path for structs, maybe this
was also the easiest way to implement typedefs but in this case not
making them proper types.

>> I did some samples with enums:
>>
>> enum {A, B} F(void) {  return A;}
>> enum {A, B} F2(void) {   return B; }
>>
>> compilers generates an error of  redefinition for the enum.
>
> Because A and B exist in the same namespace as normal identifiers, so
> here they clash.
>
>
>> This is fine:
>>
>> enum {A, B} F(void) {
>>      return B;
>> }
>>
>> int main(){
>>      if (F() == A)  { }
>> }
>>
>> But this is an error:
>>
>> void F(enum {A, B} e) {}
>> int main() {
>>      F(A);
>> }
>
> Because A exists only in the scope of F.
>
>
>> and this
>> void F(enum {A, B} e) {}
>> void F2(enum {A, B} e) {}
>> is a warning
>
> I guess this is the same warning you would have got in the last example?
> (As well as the error due to undefined A.)

The "rule" is that types defined on function return are global
but function parameters works like the types were inside the
function.

Something that may make sense with the old parameter declaration
style and very confusing now. Because someone must call the function
then the parameter type must be public but it is not.

>> This is just curiosity.
>>
>> In other topics I already said that this could be useful
>> to create parametrized structs using macros.
>>
>> for instance:
>> void F(dynamic_array(int)* a){}
>>
>> Maybe the word extern could be used to create this feature
>> without breaking compatibly.
>>
>> void F(extern struct { int* data; int size, capacity; } * a){
>> }
>>
>
> Personally I don't like in-place struct definitions at all.

The argument I have is that some types does not need names. Names
just make them less readable and just remove information.

For comparison, assume each time you use a C array you have
to declare a name.

For instance instead of

void F(int ar[])

you need

void F(int_array* a);

This is exactly what happened when we use dynamic arrays
in C. We need a name for them and it is impossible to know
what it does without looking at the details.
Differently of int a[] that we know the semantics.
With parametrized types we know the semantics without adding
these extra names.

Re: Distinction between identical struct types

<sccubl$9b2$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17431&group=comp.lang.c#17431

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: andreyta...@hotmail.com (Andrey Tarasevich)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: Sat, 10 Jul 2021 13:01:54 -0700
Organization: A noiseless patient Spider
Lines: 47
Message-ID: <sccubl$9b2$1@dont-email.me>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 20:01:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="9d40fa247645586bd853c1a757b0d972";
logging-data="9570"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/78VmWOtP/5JgKHWz9G2OY"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:Vo5x/xwY1Q7TzujB1tvfOaIhPE0=
In-Reply-To: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Content-Language: en-US
 by: Andrey Tarasevich - Sat, 10 Jul 2021 20:01 UTC

On 7/10/2021 5:41 AM, Thiago Adams wrote:
> Does anyone know or can see a reason why the C language makes
> distinction between identical struct types?

Because in C a struct declaration is a type declaration, which
introduces a new named type `struct <tag>`.

> Compare with functions:
>
> void F(void (*pf)(void)){}

Syntactic constructs that describe function type (or function pointer
type) are not type declarations. They do not introduce new named types.

That's the critical distinction between the two.

> Like this:
>
> void F(struct {int i; }* p){}
>
> int main() {
> struct { int i; } s;
> F(&s);
> }
>

Your example is an odd one: you omitted the struct tag. This is legal
but this provides no special treatment for that struct declaration. It
still declares a new type, which just happens to be tagless.
Nevertheless, two identical struct declarations, named or not, declare
two different types.

> Must be something with padding?

Nope. Why?

> But why, we are inside the same compiler?

Because that's how the language is defined.

Things get more loose one we start talking about type compatibility
across different translation units, for obvious reasons. But in the same
translation unit it is pretty strict.

--
Best regards,
Andrey Tarasevich

Re: Distinction between identical struct types

<ca98f3e1-113c-4bdf-b956-553baecf2618n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17432&group=comp.lang.c#17432

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a05:620a:244c:: with SMTP id h12mr15300123qkn.249.1625947326447;
Sat, 10 Jul 2021 13:02:06 -0700 (PDT)
X-Received: by 2002:ae9:de47:: with SMTP id s68mr44203382qkf.39.1625947326302;
Sat, 10 Jul 2021 13:02:06 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Sat, 10 Jul 2021 13:02:06 -0700 (PDT)
In-Reply-To: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2a00:23a8:400a:5601:1de:ee6e:6436:b0ef;
posting-account=Dz2zqgkAAADlK5MFu78bw3ab-BRFV4Qn
NNTP-Posting-Host: 2a00:23a8:400a:5601:1de:ee6e:6436:b0ef
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <ca98f3e1-113c-4bdf-b956-553baecf2618n@googlegroups.com>
Subject: Re: Distinction between identical struct types
From: malcolm....@gmail.com (Malcolm McLean)
Injection-Date: Sat, 10 Jul 2021 20:02:06 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Malcolm McLean - Sat, 10 Jul 2021 20:02 UTC

On Saturday, 10 July 2021 at 13:41:07 UTC+1, Thiago Adams wrote:
> Does anyone know or can see a reason why the C language makes
> distinction between identical struct types?
>
A point and a vector both have the same fields.
However if you declare both a struct point and a struct vector in the
same program, then presumably you want to enforce the distiction
between them. Subtracting two points yields a vector, for example.

So you won't want the language to allow you to override that
distinction too easily.

Re: Distinction between identical struct types

<sccujg$b2k$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17433&group=comp.lang.c#17433

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: Distinction between identical struct types
Date: Sat, 10 Jul 2021 21:06:04 +0100
Organization: A noiseless patient Spider
Lines: 95
Message-ID: <sccujg$b2k$1@dont-email.me>
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
<scc5ig$i8o$1@dont-email.me>
<dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
<sccff6$4j8$1@dont-email.me> <902be7e1-21af-5fa2-3dec-27dc6c9e8793@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 10 Jul 2021 20:06:08 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="14805d52f873d2cc66c74748411bc56e";
logging-data="11348"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Xs/i9pfC4+oETyAe+SjD+RbUw2pi0Dmk="
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:WKMd2TGhWMITdMpZjXQS3OFR2d8=
In-Reply-To: <902be7e1-21af-5fa2-3dec-27dc6c9e8793@gmail.com>
X-Antivirus-Status: Clean
Content-Language: en-GB
X-Antivirus: AVG (VPS 210710-4, 10/7/2021), Outbound message
 by: Bart - Sat, 10 Jul 2021 20:06 UTC

On 10/07/2021 20:28, Thiago Adams wrote:
> Bart wrote:
>> On 10/07/2021 16:14, Thiago Adams wrote:

>>> Using typedefs different types
>>> are compatible if they have the same layout (underline type). (like
>>> BOOL and int)
>
> Using the same reasoning of the easiest path for structs, maybe this
> was also the easiest way to implement typedefs but in this case not
> making them proper types.

Making them proper types is a big deal. Before you know it, you will
have to implement half of C++ or Ada to deal with type hierarchies,
inheritance and the rest:

typedef int T;
typedef int U;

T a; U b;

What happens with a+b; should it be allowed, what does it mean, and what
is the result type? What about a+1?

>> I guess this is the same warning you would have got in the last
>> example? (As well as the error due to undefined A.)
>
>
>
> The "rule" is that types defined on function return are global
> but function parameters works like the types were inside the
> function.
>
> Something that may make sense with the old parameter declaration
> style and very confusing now. Because someone must call the function
> then the parameter type must be public but it is not.

The parameter list is not really public, but is accessible to the compiler.

New types with associated names (structs/enums) constructed inside a
parameter list are also accessible to the compiler, but it needs the
names to check compatibility, and those names have to be resolved within
normal scope rules.

My view is that it was silly to allow such types to be created inside a
parameter list.

>> Personally I don't like in-place struct definitions at all.
>
> The argument I have is that some types does not need names. Names
> just make them less readable and just remove information.
>
> For comparison, assume each time you use a C array you have
> to declare a name.
>
> For instance instead of
>
> void F(int ar[])
>
> you need
>
> void F(int_array* a);
>
> This is exactly what happened when we use dynamic arrays
> in C. We need a name for them and it is impossible to know
> what it does without looking at the details.
> Differently of int a[] that we know the semantics.
> With parametrized types we know the semantics without adding
> these extra names.

C allows you to construct new types using * and [] modifiers. Those do
not involve new identifiers, so you don't have the problem of scope to
contend with.

You can also construct function types using () modifiers. There the
names of the parameters are optional, but are not accessible from C code
so it doesn't matter.

But struct{} and enum{} types do involve adding new identifiers which
may be necessary to access in order to use the type. Then you have the
problem of scope.

This is why it makes sense to formally define such types outside a
function, in global scope, where they are fully visible.

After all a struct{} or enum{} type may involve dozens (or hundreds) of
lines and new identifiers, not like a type like 'int(*)[]' which
occupies a fraction of a line, is anonymous, and so more suitable for
constructing in-line.

Re: Distinction between identical struct types

<677a7e6b-423f-48c3-8379-dd8d7db8af9fn@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17436&group=comp.lang.c#17436

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a37:681:: with SMTP id 123mr2662025qkg.453.1625953177263; Sat, 10 Jul 2021 14:39:37 -0700 (PDT)
X-Received: by 2002:a05:620a:16da:: with SMTP id a26mr24432458qkn.7.1625953177018; Sat, 10 Jul 2021 14:39:37 -0700 (PDT)
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!tr1.eu1.usenetexpress.com!feeder.usenetexpress.com!tr3.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Sat, 10 Jul 2021 14:39:36 -0700 (PDT)
In-Reply-To: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=2600:1003:b46e:506b:b0fb:cd86:75b4:7553; posting-account=Ix1u_AoAAAAILVQeRkP2ENwli-Uv6vO8
NNTP-Posting-Host: 2600:1003:b46e:506b:b0fb:cd86:75b4:7553
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <677a7e6b-423f-48c3-8379-dd8d7db8af9fn@googlegroups.com>
Subject: Re: Distinction between identical struct types
From: jameskuy...@alumni.caltech.edu (james...@alumni.caltech.edu)
Injection-Date: Sat, 10 Jul 2021 21:39:37 +0000
Content-Type: text/plain; charset="UTF-8"
Lines: 89
 by: james...@alumni.calt - Sat, 10 Jul 2021 21:39 UTC

On Saturday, July 10, 2021 at 8:41:07 AM UTC-4, Thiago Adams wrote:
> Does anyone know or can see a reason why the C language makes
> distinction between identical struct types?
>
> Like this:
>
> void F(struct {int i; }* p){}
>
> int main() {
> struct { int i; } s;
> F(&s);
> }
>
> Compare with functions:
>
> void F(void (*pf)(void)){}
> void F2(void) {}
> int main()
> {
> void (*pf)(void) = F2;
> F(pf);
> }
>
> Must be something with padding?
> But why, we are inside the same compiler?
> How safe we are doing a cast?

First, what the relevant rules are: The key point is that
"The presence of a struct-declaration-list in a struct-or-union-specifier
declares a new type, within a translation unit." (6.7.2.1p8).
Note that it is a new type, distinct from any previously declared type,
regardless of whether it has the same layout.

In many places, the standard imposes a constraint that two types be
compatible, or declares the behaviour is undefined if they aren't. Two
types are, in general, incompatible unless the standard explicitly says
otherwise. The only such statement that applies to structure types is:

"... two structure,
union, or enumerated types declared in separate translation units are
compatible if their tags and members satisfy the following
requirements: If one is declared with a tag, the other shall be declared
with the same tag. If both are completed anywhere within their
respective translation units, then the following additional
requirements apply: there shall be a one-to-one correspondence
between their members such that each pair of corresponding
members are declared with compatible types; if one member of the
pair is declared with an alignment specifier, the other is declared with
an equivalent alignment specifier; and if one member of the pair is
declared with a name, the other is declared with the same name. For
two structures, corresponding members shall be declared in the
same order. For two structures or unions, corresponding bit-fields
shall have the same widths. For two enumerations, corresponding
members shall have the same values." (6.2.7p10).

Note that two different struct types that would be compatible if
declared in separate translation units would not be compatible if
declared in the same translation unit.

The second point is, why? That 6.2.7p10 applies only to "types
declared in separate translation units" is clearly deliberate, it's not
something that could have been written that way due to an
oversight. Well, it's really rather basic. You shouldn't define the
structure of a struct type twice. If you intend to use it in two
different translation units, you satisfy that requirement by defining
that structure in one header file, to be #included into both
translation units, and 6.2.7p10 is what permits that to work. If you
intend to use it in two different locations within a single translation
unit, you have several options for defining it only once:

1. Declare a tag for that type once, and use that tag in all of the
other locations:
struct tag { int i;} a;
struct tag *func(struct tag*);

2. Declare a typedef for the type:
typedef struct { int i;} tag;
tag a;
tag *func(tag *);

3. Declare all objects based upon the type in a single declaration:

struct {int i;} singleItem, array[6], *pointer;

I believe that the reason why 6.2.7p10 is restricted to declarations
in different translation units was that the committee wanted to
make sure you used one of those three alternatives when using
the same struct type in multiple contexts in a single translation
units. Any of those approaches makes it far easier to identify
when two expressions have the same type.

Re: Distinction between identical struct types

<A%OGI.1372$qL.755@fx14.iad>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17470&group=comp.lang.c#17470

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!news.uzoreto.com!feeder5.feed.usenet.farm!feeder1.feed.usenet.farm!feed.usenet.farm!peer01.ams4!peer.am4.highwinds-media.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx14.iad.POSTED!not-for-mail
Subject: Re: Distinction between identical struct types
Newsgroups: comp.lang.c
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
From: Rich...@Damon-Family.org (Richard Damon)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0)
Gecko/20100101 Thunderbird/78.11.0
MIME-Version: 1.0
In-Reply-To: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: 7bit
Lines: 47
Message-ID: <A%OGI.1372$qL.755@fx14.iad>
X-Complaints-To: abuse@easynews.com
Organization: Forte - www.forteinc.com
X-Complaints-Info: Please be sure to forward a copy of ALL headers otherwise we will be unable to process your complaint properly.
Date: Sun, 11 Jul 2021 21:52:00 -0600
X-Received-Bytes: 2405
 by: Richard Damon - Mon, 12 Jul 2021 03:52 UTC

On 7/10/21 7:41 AM, Thiago Adams wrote:
> Does anyone know or can see a reason why the C language makes
> distinction between identical struct types?
>
> Like this:
>
> void F(struct {int i; }* p){}
>
> int main() {
> struct { int i; } s;
> F(&s);
> }
>
> Compare with functions:
>
> void F(void (*pf)(void)){}
> void F2(void) {}
> int main()
> {
> void (*pf)(void) = F2;
> F(pf);
> }
>
> Must be something with padding?
> But why, we are inside the same compiler?
> How safe we are doing a cast?
>
>

You are only allowed to define a give type ONCE in a translation unit.
That is a standard rule in C. The compiler isn't required to check if
two definitions are somehow the same, it is always an error to define a
given type twice.

Thus, you NEVER can have two actual definitions for a given type 'be the
same type'

Note, that while the types aren't the same, and pointers aren't
'compatible' in the sense that you can freely take a pointer to one
become a pointer to the other, the layouts of the two structs must be
the same, as both are layout compatible with a struct defined the same
in another translation unit.

One side effect of this definition rule is that it almost NEVER makes
sense to define an unnamed structure as part of the declaration of
function as you can't ever create thqt type to pass to it. (At best, you
could pass a void* pointer that gets converted to that type).

Re: Distinction between identical struct types

<877cddad-d72d-4f1b-8e9a-9fbf6db41647n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17800&group=comp.lang.c#17800

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a05:622a:390:: with SMTP id j16mr20574307qtx.266.1628026509474;
Tue, 03 Aug 2021 14:35:09 -0700 (PDT)
X-Received: by 2002:a37:9c12:: with SMTP id f18mr23059637qke.7.1628026509257;
Tue, 03 Aug 2021 14:35:09 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Tue, 3 Aug 2021 14:35:09 -0700 (PDT)
In-Reply-To: <A%OGI.1372$qL.755@fx14.iad>
Injection-Info: google-groups.googlegroups.com; posting-host=189.6.252.155; posting-account=xFcAQAoAAAAoWlfpQ6Hz2n-MU9fthxbY
NNTP-Posting-Host: 189.6.252.155
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com> <A%OGI.1372$qL.755@fx14.iad>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <877cddad-d72d-4f1b-8e9a-9fbf6db41647n@googlegroups.com>
Subject: Re: Distinction between identical struct types
From: thiago.a...@gmail.com (Thiago Adams)
Injection-Date: Tue, 03 Aug 2021 21:35:09 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Thiago Adams - Tue, 3 Aug 2021 21:35 UTC

On Monday, July 12, 2021 at 12:52:13 AM UTC-3, Richard Damon wrote:
> On 7/10/21 7:41 AM, Thiago Adams wrote:
> > Does anyone know or can see a reason why the C language makes
> > distinction between identical struct types?
> >
> > Like this:
> >
> > void F(struct {int i; }* p){}
> >
> > int main() {
> > struct { int i; } s;
> > F(&s);
> > }
> >
> > Compare with functions:
> >
> > void F(void (*pf)(void)){}
> > void F2(void) {}
> > int main()
> > {
> > void (*pf)(void) = F2;
> > F(pf);
> > }
> >
> > Must be something with padding?
> > But why, we are inside the same compiler?
> > How safe we are doing a cast?
> >
> >
> You are only allowed to define a give type ONCE in a translation unit.
> That is a standard rule in C. The compiler isn't required to check if
> two definitions are somehow the same, it is always an error to define a
> given type twice.
>
> Thus, you NEVER can have two actual definitions for a given type 'be the
> same type'
>
> Note, that while the types aren't the same, and pointers aren't
> 'compatible' in the sense that you can freely take a pointer to one
> become a pointer to the other, the layouts of the two structs must be
> the same, as both are layout compatible with a struct defined the same
> in another translation unit.
>
> One side effect of this definition rule is that it almost NEVER makes
> sense to define an unnamed structure as part of the declaration of
> function as you can't ever create thqt type to pass to it. (At best, you
> could pass a void* pointer that gets converted to that type).

There is one proposal to make structs compatible (fount it after
starting this topic.)

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2366.pdf

There are more reasons into this proposal but my motivation to create
parametrized types are included there.

Re: Distinction between identical struct types

<4dcd25bb-d546-4aad-9d4f-6a0dc8499516n@googlegroups.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17954&group=comp.lang.c#17954

  copy link   Newsgroups: comp.lang.c
X-Received: by 2002:a05:620a:88c:: with SMTP id b12mr144108qka.483.1628825593424;
Thu, 12 Aug 2021 20:33:13 -0700 (PDT)
X-Received: by 2002:a05:622a:60e:: with SMTP id z14mr127099qta.381.1628825593157;
Thu, 12 Aug 2021 20:33:13 -0700 (PDT)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c
Date: Thu, 12 Aug 2021 20:33:12 -0700 (PDT)
In-Reply-To: <sccff6$4j8$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=24.207.183.245; posting-account=G1KGwgkAAAAyw4z0LxHH0fja6wAbo7Cz
NNTP-Posting-Host: 24.207.183.245
References: <01999c52-112d-4e36-b120-e9e439e75aa7n@googlegroups.com>
<scc5ig$i8o$1@dont-email.me> <dd1d2ab8-7fcc-4e6d-a91e-59243f5fce66n@googlegroups.com>
<sccff6$4j8$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <4dcd25bb-d546-4aad-9d4f-6a0dc8499516n@googlegroups.com>
Subject: Re: Distinction between identical struct types
From: luser.dr...@gmail.com (luser droog)
Injection-Date: Fri, 13 Aug 2021 03:33:13 +0000
Content-Type: text/plain; charset="UTF-8"
 by: luser droog - Fri, 13 Aug 2021 03:33 UTC

On Saturday, July 10, 2021 at 10:48:02 AM UTC-5, Bart wrote:
> On 10/07/2021 16:14, Thiago Adams wrote:
> > But this is an error:
> >
> > void F(enum {A, B} e) {}
> > int main() {
> > F(A);
> > }
> Because A exists only in the scope of F.
> > and this
> > void F(enum {A, B} e) {}
> > void F2(enum {A, B} e) {}
> > is a warning
> I guess this is the same warning you would have got in the last example?
> (As well as the error due to undefined A.)

It's worse than that. It only exists within the scope of the functions'
argument lists. You can't use it in the bodies of F(), F1(), or F2().

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor