Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Code Reviews

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

71%
+3 −0
Code Reviews New elementsof() operator

I don't really see what good elementsof would do since sizeof(arr)/sizeof(*arr) is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code. IMO ...

posted 3mo ago by Lundin‭  ·  edited 3mo ago by Lundin‭

Answer
#3: Post edited by user avatar Lundin‭ · 2024-08-15T14:45:16Z (3 months ago)
  • I don't really see what good `elementsof` would do since `sizeof(arr)/sizeof(*arr)` is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code.
  • IMO the C committee should be focusing on fixing known problems and weeding out poorly-defined behavior, instead of inventing new features that nobody asked for. Which in turn brings on more poorly-defined behavior nobody considered... just look at C23 function attributes, it's a mess.
  • ---
  • One obvious problem that needs consideration is VLA. C already struggles with `sizeof(vla)` being evaluated in run-time. Meaning that this `elementsof` would too need to be evaluated in run-time, if given a VLA as parameter, as mentioned in the text.
  • But in order to determine if something is a VLA or not, we need to know if the array bounds is an integer constant expression or not. And there
  • programmers struggle, as seen in your examples:
  • `elementsof(int [7][n++]); // integer constant expression`
  • No, that's not an integer constant expression. The constraits for constant expressions do not allow increment/decrement or assignment etc.
  • Even if the meaning of the example was to say that `n++` is not considered since `7` is an integer constant expression, then what about `[n][expr]`? `[n]` cannot be an integer constant expression either, if `n` is a declared object/lvalue. Some compilers do controversial things when faced with such, since C allows implementation-defined constant expressions, but that was always a very poor rationale.
  • If the C language was to be changed, then this ambiguous text in 6.6 "An implementation may accept other forms of constant expressions" needs to be fixed, ideally by just removing that line. Because the current state of both clang and gcc is abusing this, while (to my knowledge) no other compiler on the market does so. I've had real world safety and portability problems caused by this, when gcc suddenly decided to change its behavior at a whim between versions. Quality implementations ought to not do that.
  • ---
  • Getting back to `elementsof`. Another corner case: what is it to do when handed an array of incomplete type? Consider for example:
  • ```c
  • int arr[3];
  • int (*arrptr)[3] = &arr;
  • int (*genptr)[] = arrptr;
  • elementsof(*genptr) // constraint violation?
  • ```
  • And what if I lie to the compiler? `elementsof( (int(*)[4])arrptr )`. The effective type here is supposedly `int [3]` or maybe `int` (we can't tell from the standard). But the operator should return 4, or...?
  • I don't really see what good `elementsof` would do since `sizeof(arr)/sizeof(*arr)` is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code.
  • IMO the C committee should be focusing on fixing known problems and weeding out poorly-defined behavior, instead of inventing new features that nobody asked for. Which in turn brings on more poorly-defined behavior nobody considered... just look at C23 function attributes, it's a mess.
  • ---
  • One obvious problem that needs consideration is VLA. C already struggles with `sizeof(vla)` being evaluated in run-time. Meaning that this `elementsof` would too need to be evaluated in run-time, if given a VLA as parameter, as mentioned in the text.
  • But in order to determine if something is a VLA or not, we need to know if the array bounds is an integer constant expression or not. And there
  • programmers struggle, as seen in your examples:
  • `elementsof(int [7][n++]); // integer constant expression`
  • No, that's not an integer constant expression. The constraits for constant expressions do not allow increment/decrement or assignment etc.
  • Even if the meaning of the example was to say that `n++` is not considered since `7` is an integer constant expression, then what about `[n][expr]`? `[n]` cannot be an integer constant expression either, if `n` is a declared object/lvalue. Some compilers do controversial things when faced with such, since C allows implementation-defined constant expressions, but that was always a very poor rationale.
  • If the C language was to be changed, then this ambiguous text in 6.6 "An implementation may accept other forms of constant expressions" needs to be fixed, ideally by just removing that line. Because the current state of both clang and gcc is abusing this, while (to my knowledge) no other compiler on the market does so. I've had real world safety and portability problems caused by this, when gcc suddenly decided to change its behavior at a whim between versions. Quality implementations ought to not do that.
  • ---
  • Getting back to `elementsof`. Another corner case: what is it to do when handed an array of incomplete type? Consider for example:
  • ```c
  • int arr[3];
  • int (*arrptr)[3] = &arr;
  • int (*genptr)[] = arrptr;
  • elementsof(*genptr) // constraint violation?
  • ```
  • And what if I lie to the compiler? `elementsof( * (int(*)[4])arrptr )`. The effective type here is supposedly `int [3]` or maybe `int` (we can't tell from the standard). But the operator should return 4, or...?
#2: Post edited by user avatar Lundin‭ · 2024-08-15T14:44:29Z (3 months ago)
  • I don't really see what good `elementsof` would do since `sizeof(arr)/sizeof(*arr)` is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code.
  • IMO the C committee should be focusing on fixing known problems and weeding out poorly-defined behavior, instead of inventing new features that nobody asked for. Which in turn brings on more poorly-defined behavior nobody considered... just look at C23 function attributes, it's a mess.
  • ---
  • One obvious problem that needs consideration is VLA. C already struggles with `sizeof(vla)` being evaluated in run-time. Meaning that this `elementsof` would too need to be evaluated in run-time, if given a VLA as parameter, as mentioned in the text.
  • But in order to determine if something is a VLA or not, we need to know if the array bounds is an integer constant expression or not. And there
  • programmers struggle, as seen in your examples:
  • `elementsof(int [7][n++]); // integer constant expression`
  • No, that's not an integer constant expression. The constraits for constant expressions do not allow increment/decrement or assignment etc.
  • Furthermore, `[n]` cannot be an integer constant expression either, if `n` is a declared object/lvalue. Some compilers do controversial things when faced with such, since C allows implementation-defined constant expressions, but that was always a very poor rationale.
  • If the C language was to be changed, then this ambiguous text in 6.6 "An implementation may accept other forms of constant expressions" needs to be fixed, ideally by just removing that line. Because the current state of both clang and gcc is abusing this, while (to my knowledge) no other compiler on the market does so. I've had real world safety and portability problems caused by this, when gcc suddenly decided to change its behavior at a whim between versions. Quality implementations ought to not do that.
  • ---
  • Getting back to `elementsof`. Another corner case: what is it to do when handed an array of incomplete type? Consider for example:
  • ```c
  • int arr[3];
  • int (*arrptr)[3] = &arr;
  • int (*genptr)[] = arrptr;
  • elementsof(*genptr) // constraint violation?
  • ```
  • And what if I lie to the compiler? `elementsof( (int(*)[4])arrptr )`. The effective type here is supposedly `int [3]` or maybe `int` (we can't tell from the standard). But the operator should return 4, or...?
  • I don't really see what good `elementsof` would do since `sizeof(arr)/sizeof(*arr)` is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code.
  • IMO the C committee should be focusing on fixing known problems and weeding out poorly-defined behavior, instead of inventing new features that nobody asked for. Which in turn brings on more poorly-defined behavior nobody considered... just look at C23 function attributes, it's a mess.
  • ---
  • One obvious problem that needs consideration is VLA. C already struggles with `sizeof(vla)` being evaluated in run-time. Meaning that this `elementsof` would too need to be evaluated in run-time, if given a VLA as parameter, as mentioned in the text.
  • But in order to determine if something is a VLA or not, we need to know if the array bounds is an integer constant expression or not. And there
  • programmers struggle, as seen in your examples:
  • `elementsof(int [7][n++]); // integer constant expression`
  • No, that's not an integer constant expression. The constraits for constant expressions do not allow increment/decrement or assignment etc.
  • Even if the meaning of the example was to say that `n++` is not considered since `7` is an integer constant expression, then what about `[n][expr]`? `[n]` cannot be an integer constant expression either, if `n` is a declared object/lvalue. Some compilers do controversial things when faced with such, since C allows implementation-defined constant expressions, but that was always a very poor rationale.
  • If the C language was to be changed, then this ambiguous text in 6.6 "An implementation may accept other forms of constant expressions" needs to be fixed, ideally by just removing that line. Because the current state of both clang and gcc is abusing this, while (to my knowledge) no other compiler on the market does so. I've had real world safety and portability problems caused by this, when gcc suddenly decided to change its behavior at a whim between versions. Quality implementations ought to not do that.
  • ---
  • Getting back to `elementsof`. Another corner case: what is it to do when handed an array of incomplete type? Consider for example:
  • ```c
  • int arr[3];
  • int (*arrptr)[3] = &arr;
  • int (*genptr)[] = arrptr;
  • elementsof(*genptr) // constraint violation?
  • ```
  • And what if I lie to the compiler? `elementsof( (int(*)[4])arrptr )`. The effective type here is supposedly `int [3]` or maybe `int` (we can't tell from the standard). But the operator should return 4, or...?
#1: Initial revision by user avatar Lundin‭ · 2024-08-15T14:41:35Z (3 months ago)
I don't really see what good `elementsof` would do since `sizeof(arr)/sizeof(*arr)` is pretty idiomatic C and problem-free given that you know what you are doing, as is the case with most C code. 

IMO the C committee should be focusing on fixing known problems and weeding out poorly-defined behavior, instead of inventing new features that nobody asked for. Which in turn brings on more poorly-defined behavior nobody considered... just look at C23 function attributes, it's a mess.

---

One obvious problem that needs consideration is VLA. C already struggles with `sizeof(vla)` being evaluated in run-time. Meaning that this `elementsof` would too need to be evaluated in run-time, if given a VLA as parameter, as mentioned in the text.

But in order to determine if something is a VLA or not, we need to know if the array bounds is an integer constant expression or not. And there
programmers struggle, as seen in your examples:

`elementsof(int [7][n++]);  // integer constant expression`

No, that's not an integer constant expression. The constraits for constant expressions do not allow increment/decrement or assignment etc.

Furthermore, `[n]` cannot be an integer constant expression either, if `n` is a declared object/lvalue. Some compilers do controversial things when faced with such, since C allows implementation-defined constant expressions, but that was always a very poor rationale.

If the C language was to be changed, then this ambiguous text in 6.6 "An implementation may accept other forms of constant expressions" needs to be fixed, ideally by just removing that line. Because the current state of both clang and gcc is abusing this, while (to my knowledge) no other compiler on the market does so. I've had real world safety and portability problems caused by this, when gcc suddenly decided to change its behavior at a whim between versions. Quality implementations ought to not do that.

---

Getting back to `elementsof`. Another corner case: what is it to do when handed an array of incomplete type? Consider for example:

```c
int arr[3];
int (*arrptr)[3] = &arr;
int (*genptr)[] = arrptr;
elementsof(*genptr) // constraint violation?
```

And what if I lie to the compiler? `elementsof( (int(*)[4])arrptr )`. The effective type here is supposedly `int [3]` or maybe `int` (we can't tell from the standard). But the operator should return 4, or...?