Pointers to VLA's
Asked Answered
V

1

8

As you may know, VLA's haves pros and cons and they are optional in C11.

I suppose that the main reason to make VLA's optional is: "the stack can blow up":

int arr[n]; /* where n = 1024 * 1024 * 1024 */

but what about pointer to VLA's?

int m, n;

scanf("%d %d", &m, &n);

int (*ptr)[n] = malloc(sizeof(int [m][n]));

In this case, there is no risk to blow up the stack, and IMO they are extremely useful.

My question is:

Could the committee have preserved pointers to VLA's, making the VLA's to non-pointer types optional?

Or one thing implies the other?

(Excuse my poor english)

Vespid answered 18/11, 2018 at 9:0 Comment(9)
It's not PC, but I think the main reason to make VLA's optional is so that MS could pretend they have a standard compliant compilerWelch
int (*ptr)[n] is just a pointer to an array of size n. The n here can be completely ignored by the compiler as it has no purpose. int *ptr; is exactly the same.Allseed
@PaulOgilvie - The n affects how the pointer arithmetic is done on ptr. It most certainly cannot be ignored.Welch
@StoryTeller, can you give me an example for my understanding?Allseed
ptr + x must be equal to (char*)ptr + x * (sizeof(int[n])) - usual pointer arithmetic in arrays. Same as if the row size was a constant expression. In this case it just isn't.Welch
@PaulOgilvie ptr + 1 = ptr + 4 bytes if you declare int *ptr;, ptr + 1 = ptr + (4 bytes * n) using a pointer to VLAVespid
So ptr + i, being equal to ptr[i] and addresses the ith row of the array. How to address an individual int? (My apologies to distract from Keine Lust's original question).Allseed
@PaulOgilvie - ptr[i][j] will address an individual int.Welch
All clear. Many thanks.Allseed
W
3

Preserving pointers to variably modifiable types would require an implementation to support about 90% of the VLA specification. The reason is the effective type rule:

6.5 Expressions

¶6 The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

After an access via ptr to the malloced memory, the effective type of the object is a VLA type. So an implementation will need to support those semantics correctly. The only thing that can be left "optional" is the ability to declare VLA's with automatic storage duration...

int boo[n];

... which is kinda silly. If an implementation supports most of VLA semantics for dynamically allocated objects, it may as well allow declaring them as objects with automatic storage duration. The committee wanted it to be truly optional, so that means pointers to VLA types had to go too.

Welch answered 18/11, 2018 at 9:40 Comment(4)
I don't think this answer is correct. There is no work at all in implementing effective type rules except to perform optimization based on non-aliasing, and an implementor can omit whichever rules they like, because the rules apply to conforming applications not implementations. On the other hand, automatic storage VLAs necessarily interact with low-level backend stuff.Sekyere
@R.. - The question was about the standard's pov. The amount of specification that will need to be hacked and slashed around the effective type rule looks non-trivial to me. Of course implementations can implement whatever.Welch
The quote is mostly irrelevant as you can never store a value with an array type into an object -- you can only store values with the array's element type into elements of the array. Similarly, you can never access a value with an array type -- only elements of the array. I think StoryTeller's comment identifies the main reason.Zeller
I would say that 90% of all complains about VLAs and the implementation issues (like extra complexity and non-determinism of stack management) comes from automatic VLAs. IMO, it is a very good decision from C committee to make VLA types mandatory in C23. Only automatic VLA will stay optional.Courbevoie

© 2022 - 2024 — McMap. All rights reserved.