Author Topic: C and its many quirks  (Read 16042 times)

0 Members and 10 Guests are viewing this topic.

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
C and its many quirks
« on: January 22, 2023, 07:17:42 pm »
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

See here.

I'm mainly asking about the idea of defining a type that is an array...
« Last Edit: January 22, 2023, 07:24:42 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8058
  • Country: pl
Re: C and its many quirks
« Reply #1 on: January 22, 2023, 07:29:26 pm »
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef

No >:(
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5090
  • Country: gb
Re: C and its many quirks
« Reply #2 on: January 22, 2023, 07:37:24 pm »
No!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17774
  • Country: fr
Re: C and its many quirks
« Reply #3 on: January 22, 2023, 07:48:36 pm »
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

See here.

I'm mainly asking about the idea of defining a type that is an array...

Sadly, with the example above, you are defining an array of struct, thus combining two concepts in one.
You *did* mention that it was "mainly" about the type being an array, but this will inevitably make the topic go in all directions. Maybe it was intentional.

As to your question, my answer is: it depends. I have nothing against this per se, although I almost never do that.
But defining struct types, certainly. I always do.

My general approach, when a given type contains a fixed-size array of something, is to encapsulate said array in a struct rather than making the array the type itself.
I find it cleaner and more consistent (as for instance, you then have a type that can directly be assigned, contrary to an array.)

But that's as with almost any other programming topic. You'll get many different answers, most with amazingly strong opinions.
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #4 on: January 22, 2023, 07:53:31 pm »
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

See here.

I'm mainly asking about the idea of defining a type that is an array...

Sadly, with the example above, you are defining an array of struct, thus combining two concepts in one.
You *did* mention that it was "mainly" about the type being an array, but this will inevitably make the topic go in all directions. Maybe it was intentional.

As to your question, my answer is: it depends. I have nothing against this per se, although I almost never do that.
But defining struct types, certainly. I always do.

My general approach, when a given type contains a fixed-size array of something, is to encapsulate said array in a struct rather than making the array the type itself.
I find it cleaner and more consistent (as for instance, you then have a type that can directly be assigned, contrary to an array.)

But that's as with almost any other programming topic. You'll get many different answers, most with amazingly strong opinions.

No, the intention is as stated, to gather opinions on that kind of use of typedef, defining types that are themselves arrays. In this case 'Person' represents an array, instances of 'Person' are three element arrays.





« Last Edit: January 22, 2023, 07:57:25 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1826
  • Country: de
Re: C and its many quirks
« Reply #5 on: January 22, 2023, 08:18:56 pm »
Why should an array type not have a typedef'ed name, too? But for clarity I'd rather write

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef struct Person PersonTriple[3];

PersonTriple myTriple;

Unfortunately there is still the limitation that objects of type PersonTriple cannot be assigned, since arrays cannot be assigned.
As SiliconWizard said, this can be addressed by wrapping the array by a struct, or in C++ I could use std::array instead:

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef std:array<Person, 3> PersonTriple;

PersonTriple myTriple;
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #6 on: January 22, 2023, 08:28:47 pm »
Why should an array type not have a typedef'ed name, too? But for clarity I'd rather write

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef struct Person PersonTriple[3];

PersonTriple myTriple;

Unfortunately there is still the limitation that objects of type PersonTriple cannot be assigned, since arrays cannot be assigned.
As SiliconWizard said, this can be addressed by wrapping the array by a struct, or in C++ I could use std::array instead:

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef std:array<Person, 3> PersonTriple;

PersonTriple myTriple;

The thing I dislike about this that 'Person' as a type name does not convey the fact it is an array. It also places the bound specifier after the type name, whereas ordinarily in C we put array bounds after the variable being declared, if C did this:

Code: [Select]
uint8_t[4]   counters;

it would be more consistent, but we can't do that in C.

This might seem pedantic but I'm currently considering this as part of my design for IPL, whether to allow it or not. If not, why? if so, why?



“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3910
  • Country: it
Re: C and its many quirks
« Reply #7 on: January 22, 2023, 08:45:41 pm »
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

See here.

I'm mainly asking about the idea of defining a type that is an array...

Sadly, with the example above, you are defining an array of struct, thus combining two concepts in one.
You *did* mention that it was "mainly" about the type being an array, but this will inevitably make the topic go in all directions. Maybe it was intentional.

As to your question, my answer is: it depends. I have nothing against this per se, although I almost never do that.
But defining struct types, certainly. I always do.

My general approach, when a given type contains a fixed-size array of something, is to encapsulate said array in a struct rather than making the array the type itself.
I find it cleaner and more consistent (as for instance, you then have a type that can directly be assigned, contrary to an array.)

But that's as with almost any other programming topic. You'll get many different answers, most with amazingly strong opinions.

Same.
Defining a type that is actually an array is.. oof.
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1826
  • Country: de
Re: C and its many quirks
« Reply #8 on: January 22, 2023, 08:47:29 pm »
The thing I dislike about this that 'Person' as a type name does not convey the fact it is an array.

Just call the type name 'PersonArray', and I think it becomes self-explanatory.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17774
  • Country: fr
Re: C and its many quirks
« Reply #9 on: January 22, 2023, 08:58:06 pm »
The thing I dislike about this that 'Person' as a type name does not convey the fact it is an array.

Just call the type name 'PersonArray', and I think it becomes self-explanatory.

Well, the argument is just the same as with people not typedef'ing structs as it doesn't convey the fact they are structs (and this is why I pointed out that by mixing the two in one typedef, the OP was sure going to trigger strong reactions - double the reaction if you will! ;D )

By that reasoning, we would remove type definitions altogether. (Yuck.) Way to run in circles with decades of computer science.

 
The following users thanked this post: Siwastaja, newbrain

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #10 on: January 22, 2023, 09:01:04 pm »
The thing I dislike about this that 'Person' as a type name does not convey the fact it is an array.

Just call the type name 'PersonArray', and I think it becomes self-explanatory.

But now there's no way to declare a single 'Person' structure, the language is not helping us now but creating scenarios that are potentially troublesome, creating a situation where we have to fight it or create another typedef that's a copy of the first typedef's structure,

“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #11 on: January 22, 2023, 09:14:01 pm »
I'm trying to find out how Ada lets you declare a 'record' that itself contains other record definitions, I'm curious about the grammar...
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1826
  • Country: de
Re: C and its many quirks
« Reply #12 on: January 22, 2023, 09:14:56 pm »
But now there's no way to declare a single 'Person' structure

Why not? See again my example:

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef struct Person PersonTriple[3];

Or if you prefer to use a type name instead of a struct name, then

Code: [Select]
typedef struct {
    int age;
    int height;
} Person;

typedef Person PersonTriple[3];

'Person' (or 'struct Person') refers to the type of a single person struct, and 'PersonTriple' is the type of the array.

 

Offline magic

  • Super Contributor
  • ***
  • Posts: 8058
  • Country: pl
Re: C and its many quirks
« Reply #13 on: January 22, 2023, 09:18:30 pm »
Just call the type name Person[3], and I think it becomes self-explanatory.
FTFY.

And ditto for *Person and so on. Which is why
Does anyone here ever use or advocate this kind of contrivance:

Code: [Select]
typedef

No >:(
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17774
  • Country: fr
Re: C and its many quirks
« Reply #14 on: January 22, 2023, 09:24:27 pm »
I'm trying to find out how Ada lets you declare a 'record' that itself contains other record definitions, I'm curious about the grammar...

Pretty much all high-level languages allow this, all the way back to decades ago. I'm not sure I get what there is to find out?
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #15 on: January 22, 2023, 09:25:01 pm »
But now there's no way to declare a single 'Person' structure

Why not? See again my example:

Code: [Select]
struct {
    int age;
    int height;
} Person;

typedef struct Person PersonTriple[3];

Or if you prefer to use a type name instead of a struct name, then

Code: [Select]
typedef struct {
    int age;
    int height;
} Person;

typedef Person PersonTriple[3];

'Person' (or 'struct Person') refers to the type of a single person struct, and 'PersonTriple' is the type of the array.

Why not? As I said if a type has been declare like this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

Then there's no way to declare a single struct instance. Yes it's easy to do IF we declare it differently. By letting us declare an array type, by allowing that, it leads to situations where we have to fight the language.

If a typedef could never be an array then the problem of being sometimes unable to declare a single instance can never happen, this is an argument for not allowing this in a language that lets is define types - IMHO.
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #16 on: January 22, 2023, 09:27:34 pm »
I'm trying to find out how Ada lets you declare a 'record' that itself contains other record definitions, I'm curious about the grammar...

Pretty much all high-level languages allow this, all the way back to decades ago. I'm not sure I get what there is to find out?

An example, I want an example. I've found examples of user defined types that contain members of other user defined types, I want to see how one can declare a user defined record type that has embedded records, not types that are records but the full record definition itself, how does one nest record definitions in Ada?
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1906
  • Country: se
Re: C and its many quirks
« Reply #17 on: January 22, 2023, 09:30:36 pm »
It also places the bound specifier after the type name, whereas ordinarily in C we put array bounds after the variable being declared, if C did this:
[...]
This might seem pedantic
It's not pedantic, but shows a slightly superficial knowledge of some C syntax peculiarities.

Just remember that typedef (apart from NOT defining a new type, but only an alias) is - for syntactic convenience - a storage class specifier.
In this way, you can typedef something exactly as you would declare a variable of that type.
I like it, as I find it easier to parse, but I'm heavily biased.

Ref ISO/IEC 9899:2011: "6.7.8 Type definitions", §3 and "6.7.1 Storage-class specifiers", §5
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #18 on: January 22, 2023, 09:31:55 pm »
Here's the Ada question, how does one write this in Ada

Code: [Select]
    struct Info{
        char name[30];
        int age;
        struct address{
            char area_name[39];
            int house_no;
            char district[39];
        };
    };
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1826
  • Country: de
Re: C and its many quirks
« Reply #19 on: January 22, 2023, 10:04:59 pm »
As I said if a type has been declare like this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

Then there's no way to declare a single struct instance.

This is not limited to arrays. You can generally not refer to anonymous (unnamed) types.
In the following example you cannot refer to to the inner struct type either:

Code: [Select]
struct S {
  struct {
    int age;
    int height;
  } inner;
  int x;
};

Just declare it differently and give a name to each type you want to reference later. What's the problem?
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 190
  • Country: us
Re: C and its many quirks
« Reply #20 on: January 22, 2023, 10:10:05 pm »
Does anyone here ever use or advocate this kind of contrivance:
I'm mainly asking about the idea of defining a type that is an array...

Defining a typename alias that is an array is perfectly good as long as it implements some sort of fairly complete data type concept. For example,

Code: [Select]
typedef int Vector3D[3];

struct Point2D { int x, y; };
typedef struct Point2D Segment[2];

Nothing wrong with it. The reasoning here is no different than defining any other alias typename. Arrays are aggregates just like structs are aggregates. No need to impose any special treatment onto arrays. With one exception though: with arrays one just have to remember that naked objects of that type are not copyable. You can't assign them, you can't pass/return them by value.
« Last Edit: January 22, 2023, 10:32:06 pm by TheCalligrapher »
 
The following users thanked this post: newbrain, gf

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #21 on: January 22, 2023, 10:12:47 pm »
As I said if a type has been declare like this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

Then there's no way to declare a single struct instance.

This is not limited to arrays. You can generally not refer to anonymous (unnamed) types.
In the following example you cannot refer to to the inner struct type either:

Code: [Select]
struct S {
  struct {
    int age;
    int height;
  } inner;
  int x;
};

Just declare it differently and give a name to each type you want to reference later. What's the problem?

It's not a problem but a question raised in my OP. The question really boils down to what good reason is there to support this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

As you and others have shown we can avoid this by doing it differently, so it seems there no good reason to support this in a language in the first place. If it is used it carries the risks of being unable to declare a single element of the structure (without all kinds of fall out).

So I don't have a "problem" I think I have my answer now.

“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline TheCalligrapher

  • Regular Contributor
  • *
  • Posts: 190
  • Country: us
Re: C and its many quirks
« Reply #22 on: January 22, 2023, 10:19:09 pm »
It's not a problem but a question raised in my OP. The question really boils down to what good reason is there to support this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

What is "this" in this case? Type alias for an array? Tagless struct type? Combined declaration for a type alias and a struct type? There are to many things piled up in the above to figure out what specifically you mean by "this".

The above is a syntactically valid construct, if only a bit too convoluted. The construct itself is perfectly useful in many contexts. There are no "quirks" in it.

The potential for abuse is there (as it is there in virtually every feature if the language), but interpreting the "abusive" code does not require any additional implementational effort from the compiler. It comes for free. The language does not refuse and does not need to refuse to support something on purely cosmetic grounds (e.g. when it just "looks too convoluted").
« Last Edit: January 22, 2023, 10:23:27 pm by TheCalligrapher »
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #23 on: January 22, 2023, 10:24:40 pm »
Does anyone here ever use or advocate this kind of contrivance:
I'm mainly asking about the idea of defining a type that is an array...

Defining a typename alias that is an array is perfectly good as long as it implements some sort of fairly complete data type concept. For example,

Code: [Select]
typedef int Vector3D[3];
Nothing wrong with it. The reasoning here is no different than defining any other alias typename. Arrays are aggregates just like structs are aggregates. No need to impose any special treatment onto arrays. With one exception though: with arrays one just have to remember that values of that type are not copyable.

That's not a good counter example because 'int' exists as a distinct type already apart from the Vector3D typedef.

I'm speaking of the case where an array of some unnamed struct X is defined in a typedef named Y as an array of say 3 elements. In this case there's no way to declare 1, 2, 4, 5 etc arrays of that unnamed struct X should the need ever arise.

There are other ways to code it, my position is that the language should not allow us to do it that bad way, it's not a good or helpful feature, what it achieves can be achieved in other far safer ways.


 

“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: C and its many quirks
« Reply #24 on: January 22, 2023, 10:29:48 pm »
It's not a problem but a question raised in my OP. The question really boils down to what good reason is there to support this:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

What is "this" in this case? Type alias for an array? Tagless struct type? Combined declaration for a type alias and a struct type? There are to many things piled up in the above to figure out what specifically you mean by "this".

The above is a syntactically valid construct, if only a bit too convoluted. The construct itself is perfectly useful in many contexts. There are no "quirks" in it.

The potential for abuse is there (as it is there in virtually every feature if the language), but interpreting the "abusive" code does not require any additional implementational effort from the compiler. It comes for free. The language does not refuse and does not need to refuse to support something on purely cosmetic grounds (e.g. when it just "looks too convoluted").

"this" is a typedef array for an unnamed struct. Should we ever need 1, 2, 4, 5 elements in some other part of the code one day, then we cannot unless we do one of these:

1. Change the typedef and change every declaration of it to to now be an array.
2. Copy/paste the structure into another typedef that represents a single instance of the struct.

Therefore allowing the construct in the first place is a mistake IMHO, it serves no purpose, there are other ways to do what's intended there without needing to do 1. or 2.

You claim its useful, how? show me an example of where it is more useful than some of the other options for doing this?

Code: [Select]
typedef struct {
    int age;
    int height;
} Person[3];

Could be:

Code: [Select]
typedef struct {
    int age;
    int height;
} Person;

typedef struct {
   Person people[3];
} ThreePersonTeam;

For example. If that was the ONLY way to do it, what problems arise? what would one lose by disallowing the first approach?

From what I can see there's no downside to disallowing the definition of typedef arrays, so in a new language it would be wise to do that, disallow the capability.


« Last Edit: January 22, 2023, 10:40:32 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf