Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   VLA question (http://www.velocityreviews.com/forums/t961761-vla-question.html)

Philip Lantz 06-14-2013 05:49 AM

VLA question
 

The following declaration of v is a variable length array and is thus a
constraint violation in compilers for C prior to C99 and in
implementations for C11 that define __STDC_NO_VLA__.

void f()
{
const int n = 5;
int v[n];
...
}

For implementations that do support it, is there any reason they can't
treat it exactly as they would treat the following, regardless of what
appears in the rest of the function body?

void f()
{
const int n = 5;
int v[5];
...
}

Bart van Ingen Schenau 06-14-2013 07:28 AM

Re: VLA question
 
On Thu, 13 Jun 2013 22:49:37 -0700, Philip Lantz wrote:

> The following declaration of v is a variable length array and is thus a
> constraint violation in compilers for C prior to C99 and in
> implementations for C11 that define __STDC_NO_VLA__.
>
> void f()
> {
> const int n = 5;
> int v[n];
> ...
> }
>
> For implementations that do support it, is there any reason they can't
> treat it exactly as they would treat the following, regardless of what
> appears in the rest of the function body?
>
> void f()
> {
> const int n = 5;
> int v[5];
> ...
> }


No, there is not, because any attempt to modify `n` results in undefined
behavior and compilers are allowed to presume that there is no undefined
behavior in the programs they compile.

On the other hand, compilers are also not required to notice that `n` is
initialized with a compile-time constant and thus that this
transformation is possible.

Bart v Ingen Schenau

Keith Thompson 06-14-2013 03:37 PM

Re: VLA question
 
Bart van Ingen Schenau <bart@ingen.ddns.info.invalid> writes:
> On Thu, 13 Jun 2013 22:49:37 -0700, Philip Lantz wrote:
>> The following declaration of v is a variable length array and is thus a
>> constraint violation in compilers for C prior to C99 and in
>> implementations for C11 that define __STDC_NO_VLA__.
>>
>> void f()
>> {
>> const int n = 5;
>> int v[n];
>> ...
>> }
>>
>> For implementations that do support it, is there any reason they can't
>> treat it exactly as they would treat the following, regardless of what
>> appears in the rest of the function body?
>>
>> void f()
>> {
>> const int n = 5;
>> int v[5];
>> ...
>> }

>
> No, there is not, because any attempt to modify `n` results in undefined
> behavior and compilers are allowed to presume that there is no undefined
> behavior in the programs they compile.
>
> On the other hand, compilers are also not required to notice that `n` is
> initialized with a compile-time constant and thus that this
> transformation is possible.


Even if you could change the value of n, it wouldn't affect the VLA.
The size of a VLA is determined when it's defined:

int n = 5;
int v[n];
n = 42; /* v still has 5 elements */

VLAs are an exception to the rule that the argument of sizeof is not
evaluted, but I don't think that matters in this case. Evaluating
`sizeof v` in principle evalutes `v`, but that has no visible effects.
I'm not even sure what it means to evaluate `v`. (The rule does mean
that evaluating `sizeof int[func()]` will call func.)

One difference is type compatibility. Two array types with size
specifiers with compatible element types are compatible if their
sizes are constant and equal *or* if their sizes are not both
constant. If they're not constant and are unequal, using them in
a context that requires compatible types has undefined behavior.
(C11 6.7.6.2p6)

So this:

int v[5];
int (*ptr)[6] = v;

is a constraint violation, but this;

int n = 5;
int v[n];
int (*ptr)[6] = v;

is not a constraint violation, but its behavior is undefined.

Still, a compiler is permitted to treat them identically. It can
generate the same code for both. Most compilers will treat them
differently in the sense that they'll issue a diagnostic (or at
least a *different* diagnostic) in the first case, but I don't
think that distinction is required; when the behavior is undefined,
a diagnostic is permitted, and when the behavior is defined,
compilers can issue whatever diagnostics they like.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Stephen Sprunk 06-15-2013 07:49 PM

Re: VLA question
 
On 14-Jun-13 00:49, Philip Lantz wrote:
> The following declaration of v is a variable length array and is
> thus a constraint violation in compilers for C prior to C99 and in
> implementations for C11 that define __STDC_NO_VLA__.
>
> void f()
> {
> const int n = 5;
> int v[n];
> ...
> }


Without VLAs, array sizes are constrained to "constant integer
expressions". For some reason, a "const int" is not a "constant integer
expression", so using one as such would be a constraint violation.

This is why most "constants" in C are done with #define rather than
const int, which defeats type safety.

The C-like subset of C++ does not have this defect, so it's puzzling why
later revisions of C itself have not fixed it. This is simpler, for
instance, than introducing VLAs in the first place.

> For implementations that do support it, is there any reason they
> can't treat it exactly as they would treat the following, regardless
> of what appears in the rest of the function body?
>
> void f()
> {
> const int n = 5;
> int v[5];
> ...
> }


As far as I know, they do.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

Eric Sosman 06-15-2013 08:49 PM

Re: VLA question
 
On 6/15/2013 3:49 PM, Stephen Sprunk wrote:
> On 14-Jun-13 00:49, Philip Lantz wrote:
>> The following declaration of v is a variable length array and is
>> thus a constraint violation in compilers for C prior to C99 and in
>> implementations for C11 that define __STDC_NO_VLA__.
>>
>> void f()
>> {
>> const int n = 5;
>> int v[n];
>> ...
>> }

>
> Without VLAs, array sizes are constrained to "constant integer
> expressions". For some reason, a "const int" is not a "constant integer
> expression", so using one as such would be a constraint violation.
>
> This is why most "constants" in C are done with #define rather than
> const int, which defeats type safety.
>
> The C-like subset of C++ does not have this defect, so it's puzzling why
> later revisions of C itself have not fixed it. This is simpler, for
> instance, than introducing VLAs in the first place.
> [...]


Simpler, well, maybe -- but some complications remain:

const int n = 1 + rand() % 53;
int v[n];

Just knowing that `n' is `const' is not enough; one must also
remember things about its initializer.

extern const int n;
int v[n];

Again, just knowing that it's `const' is not enough.

One can write rules to deal with such things -- C++ has
such rules -- but the very existence of the rules shows that
"simpler" is a bit more complex than "dead easy."

--
Eric Sosman
esosman@comcast-dot-net.invalid

Stephen Sprunk 06-15-2013 10:59 PM

Re: VLA question
 
On 15-Jun-13 15:49, Eric Sosman wrote:
> On 6/15/2013 3:49 PM, Stephen Sprunk wrote:
>> Without VLAs, array sizes are constrained to "constant integer
>> expressions". For some reason, a "const int" is not a "constant
>> integer expression", so using one as such would be a constraint
>> violation.
>> ...
>> The C-like subset of C++ does not have this defect, so it's
>> puzzling why later revisions of C itself have not fixed it. This
>> is simpler, for instance, than introducing VLAs in the first
>> place. [...]

>
> Simpler, well, maybe -- but some complications remain:
>
> const int n = 1 + rand() % 53; int v[n];
>
> Just knowing that `n' is `const' is not enough; one must also
> remember things about its initializer.


Surely the compiler would know whether n's value was known or not. An
unknown value would only be allowed if VLAs were supported.

> One can write rules to deal with such things -- C++ has such rules --
> but the very existence of the rules shows that "simpler" is a bit
> more complex than "dead easy."


Fair enough. However, I think it's a reasonable to expect this to be
fixed by now, especially given the C-like subset of C++ did so long ago.
Just borrow those rules--as C has done with several other of its
improvements over the years, eg. prototypes, // comments, etc..

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking

Keith Thompson 06-15-2013 11:54 PM

Re: VLA question
 
Stephen Sprunk <stephen@sprunk.org> writes:
> On 14-Jun-13 00:49, Philip Lantz wrote:
>> The following declaration of v is a variable length array and is
>> thus a constraint violation in compilers for C prior to C99 and in
>> implementations for C11 that define __STDC_NO_VLA__.
>>
>> void f()
>> {
>> const int n = 5;
>> int v[n];
>> ...
>> }

>
> Without VLAs, array sizes are constrained to "constant integer
> expressions". For some reason, a "const int" is not a "constant integer
> expression", so using one as such would be a constraint violation.
>
> This is why most "constants" in C are done with #define rather than
> const int, which defeats type safety.


You can also define enumeration constants:

void f() {
enum { n = 5 };
int v[n];
...
}

Now v is not a VLA.

Enumeration constants can only be of type int, and this trick is
arguably an abuse of the enumeration type mechanism (the latter
doesn't particularly bother me).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson 06-16-2013 12:36 AM

Re: VLA question
 
"christian.bau" <christian.bau@cbau.wanadoo.co.uk> writes:
> On Jun 15, 11:59*pm, Stephen Sprunk <step...@sprunk.org> wrote:
>> > Just knowing that `n' is `const' is not enough; one must also
>> > remember things about its initializer.

>
> I wonder how difficult it would be to change the definition of
> "constant expression" so that it also includes expressions containing
> const variables initialised with constant expressions. Should only
> require modest changes in any compiler.


There was a lengthy discussion of this in comp.std.c a couple of years
ago (which didn't reach any real conclusions other that it hadn't been
officially proposed for C201X, and it was already too late to add it
anyway -- a moot point now.)

Look for a thread with the subject "C++-style treatment of const?",
Message-ID: <lnlix798oh.fsf@nuthaus.mib.org>.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson 06-16-2013 03:42 AM

Re: VLA question
 
Philip Lantz <prl@canterey.us> writes:
> The following declaration of v is a variable length array and is thus a
> constraint violation in compilers for C prior to C99 and in
> implementations for C11 that define __STDC_NO_VLA__.
>
> void f()
> {
> const int n = 5;
> int v[n];
> ...
> }
>
> For implementations that do support it, is there any reason they can't
> treat it exactly as they would treat the following, regardless of what
> appears in the rest of the function body?
>
> void f()
> {
> const int n = 5;
> int v[5];
> ...
> }


This doesn't directly address your question, but one difference is that
VLAs can't be initialized.

int not_a_vla[5] = { 0 }; /* ok */
int vla[n] = { 0 }; /* constraint violation */

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Tim Rentsch 06-16-2013 02:18 PM

Re: VLA question
 
Stephen Sprunk <stephen@sprunk.org> writes:

> On 15-Jun-13 15:49, Eric Sosman wrote:
>> On 6/15/2013 3:49 PM, Stephen Sprunk wrote:
>>> Without VLAs, array sizes are constrained to "constant integer
>>> expressions". For some reason, a "const int" is not a "constant
>>> integer expression", so using one as such would be a constraint
>>> violation.
>>> ...
>>> The C-like subset of C++ does not have this defect, so it's
>>> puzzling why later revisions of C itself have not fixed it. This
>>> is simpler, for instance, than introducing VLAs in the first
>>> place. [...]

>>
>> Simpler, well, maybe -- but some complications remain:
>>
>> const int n = 1 + rand() % 53; int v[n];
>>
>> Just knowing that `n' is `const' is not enough; one must also
>> remember things about its initializer.

>
> Surely the compiler would know whether n's value was known or not. An
> unknown value would only be allowed if VLAs were supported.
>
>> One can write rules to deal with such things -- C++ has such rules --
>> but the very existence of the rules shows that "simpler" is a bit
>> more complex than "dead easy."

>
> Fair enough. However, I think it's a reasonable to expect this to be
> fixed by now, especially given the C-like subset of C++ did so long ago.
> [snip]


This assumes that other people agree that it's a problem, and
obviously they don't. What are the benefits, and what makes
them worth the costs? Unless and until someone presents a
compelling argument on this question, it's unlikely that C
will adopt such a change. And rightly so.


All times are GMT. The time now is 04:49 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.