I've found examples on the Net where the arrays have been defined in a function context and the size passed as parameter
f(int n) {
char * arr[n];
...
}
That reminded me on other languages where you'd need at least a block
context for dynamically sized arrays, like
int n = 5;
{
char * arr[n];
...
}
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc, -std=C99).
Q1: Is this a correct (portable) form?
Then, with above setting, I also tried
arr[99] = "foobar";
To my astonishment the compiler did not only accept that but it also
operated without runtime error; but I assume it's an error that may
severely corrupt the memory. - Q2: Is my suspicion correct?
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:
I've found examples on the Net where the arrays have been defined in a
function context and the size passed as parameter
f(int n) {
char * arr[n];
...
}
Yes, that would be a VLA.
That reminded me on other languages where you'd need at least a block
context for dynamically sized arrays, like
int n = 5;
{
char * arr[n];
...
}
But a function body is in itself a block. Inside a function body you are already in "a block context".
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc, -std=C99).
You mean you did this at file scope? No, VLAs are illegal at file scope.
And I was unable to repeat this feat in GCC.
Q1: Is this a correct (portable) form?
VLA objects have to be declared locally. However, keep in mind that
support for local declarations of VLA _objects_ is now optional (i.e.
not portable). Support for variably-modified _types_ themselves (VLA
types) is mandatory. But you are not guaranteed to be able to declare an actual VLA variable.
[...]
On 09.02.2025 09:06, Andrey Tarasevich wrote:
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:
I've found examples on the Net where the arrays have been defined
in a function context and the size passed as parameter
f(int n) {
char * arr[n];
...
}
Yes, that would be a VLA.
That reminded me on other languages where you'd need at least a
block context for dynamically sized arrays, like
int n = 5;
{
char * arr[n];
...
}
But a function body is in itself a block. Inside a function body
you are already in "a block context".
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc,
-std=C99).
You mean you did this at file scope? No, VLAs are illegal at file
scope. And I was unable to repeat this feat in GCC.
Oh, sorry, no; above I had just written an excerpt. - Actually I had
those two examples above within a main() function. - Sorry again for
my inaccuracy.
What I meant was (with surrounding context) that I knew (from _other_ languages) a syntax like
main ()
{
int n = 5;
{
char * arr[n];
...
}
}
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
and it seemed to work that way. (In those other languages that wasn't possible.)
Q1: Is this a correct (portable) form?
VLA objects have to be declared locally. However, keep in mind that
support for local declarations of VLA _objects_ is now optional
(i.e. not portable). Support for variably-modified _types_
themselves (VLA types) is mandatory. But you are not guaranteed to
be able to declare an actual VLA variable.
I fear I don't understand what you're saying here. - By "now" do you
mean newer versions of the C standards? That you can rely only, say,
rely on it with C99 but maybe not before and not in later C standards conforming compilers?
For my purpose it would be okay to know whether with the C99 version
(that I used) it's okay, or whether that's some GNU specific extension
or some such.
Janis
[...]
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
and it seemed to work that way. (In those other languages that wasn't possible.)
Q1: Is this a correct (portable) form?
VLA objects have to be declared locally. However, keep in mind that
support for local declarations of VLA _objects_ is now optional (i.e.
not portable). Support for variably-modified _types_ themselves (VLA
types) is mandatory. But you are not guaranteed to be able to declare an
actual VLA variable.
I fear I don't understand what you're saying here. - By "now" do you
mean newer versions of the C standards? That you can rely only, say,
rely on it with C99 but maybe not before and not in later C standards conforming compilers?
For my purpose it would be okay to know whether with the C99 version
(that I used) it's okay, or whether that's some GNU specific extension
or some such.
On 09.02.2025 09:06, Andrey Tarasevich wrote:
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:
I've found examples on the Net where the arrays have been defined in a
function context and the size passed as parameter
f(int n) {
char * arr[n];
...
}
Yes, that would be a VLA.
That reminded me on other languages where you'd need at least a block
context for dynamically sized arrays, like
int n = 5;
{
char * arr[n];
...
}
But a function body is in itself a block. Inside a function body you are
already in "a block context".
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc, -std=C99).
You mean you did this at file scope? No, VLAs are illegal at file scope.
And I was unable to repeat this feat in GCC.
Oh, sorry, no; above I had just written an excerpt. - Actually I had
those two examples above within a main() function. - Sorry again for
my inaccuracy.
What I meant was (with surrounding context) that I knew (from _other_ languages) a syntax like
main ()
{
int n = 5;
{
char * arr[n];
...
}
}
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
and it seemed to work that way. (In those other languages that wasn't possible.)
Q1: Is this a correct (portable) form?
VLA objects have to be declared locally. However, keep in mind that
support for local declarations of VLA _objects_ is now optional (i.e.
not portable). Support for variably-modified _types_ themselves (VLA
types) is mandatory. But you are not guaranteed to be able to declare an
actual VLA variable.
I fear I don't understand what you're saying here. - By "now" do you
mean newer versions of the C standards?
That you can rely only, say,
rely on it with C99 but maybe not before and not in later C standards conforming compilers?
For my purpose it would be okay to know whether with the C99 version
(that I used) it's okay, or whether that's some GNU specific extension
or some such.
On Sun, 9 Feb 2025 10:54:36 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[...]
There is another problem in your code - it assigns string literal to non-const char*. It is legal, as far as 'C' Standard is concerned, but
makes very little practical sense, because any attempt to assign to
string literal through resulting pointer is UB. And not just a
theoretical UB, but a real-world UB.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
and it seemed to work that way. (In those other languages that wasn't
possible.)
Hmm, IIRC both (Extended) Pascal and PL/I allow VLA within function
in places where they allow variable declarations, so really no
special _inner block_ requirement (just must be local to a function).
On Sun 2/9/2025 1:54 AM, Janis Papanagnou wrote:
That you can rely only, say,
rely on it with C99 but maybe not before and not in later C standards
conforming compilers?
Things take some wild swings wrt to VLA support as you progress through various C standards beginning. Before C99 there was no VLA. In C99
everything VLA is required. In C11 everything VLA is optional. C23 takes
a hybrid approach: the whole thing is required, except support for
declaring automatic VLA objects is optional.
[...]
For my purpose it would be okay to know whether with the C99 version
(that I used) it's okay, or whether that's some GNU specific extension
or some such.
Formally, if you want to declare local (automatic) VLAs, then the only version of C standard with which you are completely okay is C99. Later versions make things more problematic.
However, GNU seems to be dedicated to supporting everything VLA-related.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:[...]
On 09.02.2025 09:06, Andrey Tarasevich wrote:
But a function body is in itself a block. Inside a function body you are >>> already in "a block context".
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc, -std=C99).
You mean you did this at file scope? No, VLAs are illegal at file scope. >>> And I was unable to repeat this feat in GCC.
Oh, sorry, no; above I had just written an excerpt. - Actually I had
those two examples above within a main() function. - Sorry again for
my inaccuracy.
What I meant was (with surrounding context) that I knew (from _other_
languages) a syntax like
main ()
{
int n = 5;
{
char * arr[n];
...
}
}
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
The first line needs to be `int main(void)`. The "implicit int"
misfeature was removed in C99. [...]
[...] but that's not relevant to your example).
[...]
C90 didn't have VLAs at all.
C99 introduced them and required all implementations to support them.
C11 made variably modified types optional.
C23 still makes variable length arrays with automatic storage duration optional but "Parameters declared with variable length array types are adjusted and then define objects of automatic storage duration with
pointer types. Thus, support for such declarations is mandatory."
(Support for C23 is still preliminary.)
For my purpose it would be okay to know whether with the C99 version
(that I used) it's okay, or whether that's some GNU specific extension
or some such.
C99 requires support for local objects of variable length array types.
On Sun 2/9/2025 9:19 AM, Janis Papanagnou wrote:
I had other languages in mind.[*]
Janis
[*] For example Simula:
begin
integer n;
n := inint;
begin
integer array arr (1:n);
arr(5) := 9;
end
end
(Which is also understandable, since in Simula declarations must appear
before statements in any block.)
Well, in that case your previous mentions of "block context" are not
related to VLAs at all. You apparently meant that in order to introduce
a new declaration, any new declaration "in the middle of the code" one
needs to open a new block - just because the language requires all declarations to reside at the beginning of a block.
This was the case in C90, where we also sometimes had to open new blocks
to introduce new declarations. But starting from C99 this is no longer necessary. In C99 one can simply place declarations in the middle of the
code "C++-style" (the underlying semantics is still different from C++,
but syntactically/superficially it looks pretty much the same).
I had other languages in mind.[*]
Janis
[*] For example Simula:
begin
integer n;
n := inint;
begin
integer array arr (1:n);
arr(5) := 9;
end
end
(Which is also understandable, since in Simula declarations must appear before statements in any block.)
[...] my test-wise - deliberately
wrong! - assignment to 'a[99]' produced also no compiler complaints,
On Sun, 9 Feb 2025 18:18:04 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
On 09.02.2025 11:39, Michael S wrote:
On Sun, 9 Feb 2025 10:54:36 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[...]
There is another problem in your code - it assigns string literal to
non-const char*. It is legal, as far as 'C' Standard is concerned,
but makes very little practical sense, because any attempt to
assign to string literal through resulting pointer is UB. And not
just a theoretical UB, but a real-world UB.
This comment specifically draw my attention and made me nervous.
You know, I'm rarely programming in plain "C", and while in C++
I generally try to program in "const-correct" form
Which, I suppose, is not easy.
I never make
use of 'const' in "C". - Unless the compiler complains about it,
but I don't recall it (ever?) did.
In my test application I actually never assign string literals
or strings to any other string object (modulo the buffer that I
filled with a 'fgets'). I operate solely with pointers to 'argv'
elements and to the 'char buf[]' buffer data.
Do you see any issue with that?
Janis
I see no issues.
Generally, due to absence of user-defined polymorphism, C does not have
the type of ugly surprises with constness that make life of C++
programmers miserable. Still, behavior of string literals can be
surprising.
I would guess that if it was feasible to make a breaking changes, C89
would define type of string literals as 'const char*' rather than
'char*'. But breaking changes were not feasible.
On 09.02.2025 11:39, Michael S wrote:
On Sun, 9 Feb 2025 10:54:36 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
[...]
There is another problem in your code - it assigns string literal to non-const char*. It is legal, as far as 'C' Standard is concerned,
but makes very little practical sense, because any attempt to
assign to string literal through resulting pointer is UB. And not
just a theoretical UB, but a real-world UB.
This comment specifically draw my attention and made me nervous.
You know, I'm rarely programming in plain "C", and while in C++
I generally try to program in "const-correct" form
I never make
use of 'const' in "C". - Unless the compiler complains about it,
but I don't recall it (ever?) did.
In my test application I actually never assign string literals
or strings to any other string object (modulo the buffer that I
filled with a 'fgets'). I operate solely with pointers to 'argv'
elements and to the 'char buf[]' buffer data.
Do you see any issue with that?
Janis
wrong! - assignment to 'a[99]' produced also no compiler complaints,
Formally, if you want to declare local (automatic) VLAs, then the only version of C standard with which you are completely okay is C99. Later versions make things more problematic.
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:...
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc, -std=C99).
You mean you did this at file scope? No, VLAs are illegal at file scope.
And I was unable to repeat this feat in GCC.
On 09.02.2025 09:06, Andrey Tarasevich wrote:...
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:
...Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
What I meant was (with surrounding context) that I knew (from _other_ languages) a syntax like
main ()
{
int n = 5;
{
char * arr[n];
...
}
}
And in "C" (C99) I tried it *without* the _inner block_
main ()
{
int n = 5;
char * arr[n];
...
}
On 09.02.2025 18:46, Janis Papanagnou wrote:
[...] my test-wise - deliberately
wrong! - assignment to 'a[99]' produced also no compiler complaints,
BTW, it produced also no core dump or any other runtime error.
(But it is obviously severely wrong code anyway.)
On 2/9/25 12:53, Janis Papanagnou wrote:
On 09.02.2025 18:46, Janis Papanagnou wrote:
[...] my test-wise - deliberately
wrong! - assignment to 'a[99]' produced also no compiler complaints,
BTW, it produced also no core dump or any other runtime error.
(But it is obviously severely wrong code anyway.)
Accessing an array beyond it's bounds has undefined behavior, whether or
not it is a VLA. "undefined behavior" means that the C standard imposes
no requirements on the behavior. In particular, it does not require a diagnostic message, nor a core dump, nor any other kind of runtime error.
The standard says "undefined behavior" when there are some situations
where it can be arbitrarily difficult to identify violations of a rule
at compile time. That applies to this rule, because if pointers are
used, it can be quite difficult to confirm whether or not a given access
will violate this rule.
In this particular case. however, it would be trivial to detect the violation, but none of the compilers I've tested do so.
When such code is accepted by an implementation, what is most likely to happen is that the compiler will generate code that creates an array containing "foobar", and which attempts to write a pointer to the first element of that array to the location where a[99] should be, if a had at least 100 elements. Depending upon what that piece of memory is being
used for, the results could be catastrophic, or completely innocuous, or somewhere in-between.
On Sun, 9 Feb 2025 18:46:44 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
wrong! - assignment to 'a[99]' produced also no compiler complaints,
gcc produces warning in this case, but only at optimization level of 2
or higher.
Michael S <already5chosen@yahoo.com> writes:
On Sun, 9 Feb 2025 18:18:04 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
There's no such thing as a "string object" in C. [...]
[ "C" and C++ considerations of strings character arrays, pointers ]
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
I had other languages in mind.[*]
Janis
[*] For example Simula:
begin
integer n;
n := inint;
begin
integer array arr (1:n);
arr(5) := 9;
end
end
(Which is also understandable, since in Simula declarations must appear
before statements in any block.)
Apparently Simula doesn't allow variables to be initialized in their declarations.
Because of that, `n := inint;` (where inint is actually a
call to a value-returning procedure) is a separate statement. If
Simula supported C-style initializers, then presumably the inner block
would not be needed:
begin
integer n := inint;
integer array arr (1:n);
arr(5) := 9;
end
On 2/9/25 12:53, Janis Papanagnou wrote:
On 09.02.2025 18:46, Janis Papanagnou wrote:
[...] my test-wise - deliberately
wrong! - assignment to 'a[99]' produced also no compiler complaints,
BTW, it produced also no core dump or any other runtime error.
(But it is obviously severely wrong code anyway.)
Accessing an array beyond it's bounds has undefined behavior, whether or
not it is a VLA. "undefined behavior" means that the C standard imposes
no requirements on the behavior. In particular, it does not require a diagnostic message, nor a core dump, nor any other kind of runtime error.
[...]
In this particular case. however, it would be trivial to detect the violation, but none of the compilers I've tested do so.
When such code is accepted by an implementation, what is most likely to happen is that the compiler will generate code that creates an array containing "foobar", and which attempts to write a pointer to the first element of that array to the location where a[99] should be, if a had at least 100 elements. Depending upon what that piece of memory is being
used for, the results could be catastrophic, or completely innocuous, or somewhere in-between.
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
If I'd knew the audience is picky I'd posted the whole test program;
but then there's even much more picky comments to expect. ;-)
Yeah, we're picky here.
I hope to mollify the audience if I point out that my code actually
looks *like* this
...
int main (int argc, char * argv[])
{
...
return 0;
}
(And, yes, I know that the "..." is not correct, and argc is unused,
and I omitted 'const', etc.)
It's clear enough that the "..." is figurative.
As picky as I am, I wouldn't have commented on it.
"// ..." or "/* ... */" is more
pedantically correct, but whatever.
(Incidentally, Perl has a "..." operator, nicknamed the Yada Yada
operator, intended to mark placeholder code that is not yet
implemented.)
The "return 0;" is unnecessary but harmless in C99 and later.
On 10.02.2025 01:38, Keith Thompson wrote:...
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
...int main (int argc, char * argv[])
{
...
return 0;
}
The "return 0;" is unnecessary but harmless in C99 and later.
That - returning a value when a function is declared to return
one - is actually a [maybe picky] coding-habit of mine. :-)
The "return 0;" is unnecessary but harmless in C99 and later.
That - returning a value when a function is declared to return
one - is actually a [maybe picky] coding-habit of mine. :-)
On Sun 2/9/2025 6:35 PM, Janis Papanagnou wrote:
The "return 0;" is unnecessary but harmless in C99 and later.
That - returning a value when a function is declared to return
one - is actually a [maybe picky] coding-habit of mine. :-)
This is, of course, a purely stylistic matter. But still... `main` is special.
And it kinda makes sense to acknowledge it special nature by
not doing explicit `return 0` from `main`. `main` looks cleaner without it.
On 10.02.2025 00:50, Keith Thompson wrote:
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
I had other languages in mind.[*]
Janis
[*] For example Simula:
begin
integer n;
n := inint;
begin
integer array arr (1:n);
arr(5) := 9;
end
end
(Which is also understandable, since in Simula declarations must appear
before statements in any block.)
Apparently Simula doesn't allow variables to be initialized in their
declarations.
The Cim compiler I use actually supports a constant initialization -
but I'm positive this is non-standard! - like
begin
integer n = 10;
integer array arr (1:n);
arr(5) := 9;
end
Because of that, `n := inint;` (where inint is actually a
call to a value-returning procedure) is a separate statement. If
Simula supported C-style initializers, then presumably the inner block
would not be needed:
Indeed. (See non-standard example above.)
begin
integer n := inint;
integer array arr (1:n);
arr(5) := 9;
end
This is not possible because 'n' isn't a constant here (and 'inint' is
a function, as you say). - So you're correct that the block would not
be an inherent necessity for that declaration [with Cim compiler].
A general statement for the standard Simula language cannot be given,
though, since it's undefined.
Janis
On 09/02/2025 19:19, Michael S wrote:
On Sun, 9 Feb 2025 18:46:44 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
wrong! - assignment to 'a[99]' produced also no compiler
complaints,
gcc produces warning in this case, but only at optimization level
of 2 or higher.
Which version of gcc?
Tried with gcc 14.2 (x86-64) with -Wall -O3 (or -O2, same), it
doesn't give any warning whatsoever. (And yes, same with clang.)
Cppcheck does spot it properly though:
error: Array 'arr[5]' accessed at index 99, which is out of bounds. [arrayIndexOutOfBounds]
arr[99] = "foobar";
I highly recommend using Cppcheck as a static analyzer (at the bare
minimum, there are better out there). Compilers are pretty basic in
terms of static analysis.
On 09.02.2025 21:55, James Kuyper wrote:
On 2/9/25 12:53, Janis Papanagnou wrote:
On 09.02.2025 18:46, Janis Papanagnou wrote:
[...] my test-wise - deliberately
wrong! - assignment to 'a[99]' produced also no compiler complaints,
BTW, it produced also no core dump or any other runtime error.
(But it is obviously severely wrong code anyway.)
Accessing an array beyond it's bounds has undefined behavior, whether or
not it is a VLA. "undefined behavior" means that the C standard imposes
no requirements on the behavior. In particular, it does not require a
diagnostic message, nor a core dump, nor any other kind of runtime error.
Yes. (There's reasons why I prefer programming languages with checks.)
[...]
In this particular case. however, it would be trivial to detect the
violation, but none of the compilers I've tested do so.
Yes, because it's a special case with a constant defined. But the
value may come from "outside", undetectable by the compiler and only detectable during runtime if there's additional information maintained (stored and checked).
When such code is accepted by an implementation, what is most likely to
happen is that the compiler will generate code that creates an array
containing "foobar", and which attempts to write a pointer to the first
element of that array to the location where a[99] should be, if a had at
least 100 elements. Depending upon what that piece of memory is being
used for, the results could be catastrophic, or completely innocuous, or
somewhere in-between.
Yes. That matches exactly my fears or expectations here [with "C"].
Janis
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[ Simula / Cim stuff snipped ]
[...]
But a VLA object's lifetime begins, not when execution reaches the
opening "{", but when it reaches the object definition.
[...]
Let's assume your full code is :
int main() {
int n = 5;
char * arr[n];
arr[99] = "foobar";
}
In C, that means exactly the same as a do-nothing program:
int main() { }
[...]
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
[...]
Having a "return 0;" at the end of main() is neither obsolescent nor deprecated. It's still perfectly valid, with the expected semantics.
The only that changed in C99 is that reaching the closing "}" of
the main function does an implicit "return 0;". This change was
borrowed from C++.
I do tend to dislike the change; it feels like an unnecessary special
case, and I used to advise people to add an explicit "return 0;"
anyway. This was partly because C99 compilers were relatively rare,
and there were advantages to writing code that still worked with
C90-only compilers.
I usually omit the "return 0;", but I don't object to including it --
though I will occasionally mention in passing that it's "unnecessary
but harmless". If nothing else, the history is interesting (at
least to me).
On 10.02.2025 11:39, David Brown wrote:
[...]
Let's assume your full code is :
int main() {
int n = 5;
char * arr[n];
arr[99] = "foobar";
}
This assumption is incorrect (for my case), so all derived possible implications like
In C, that means exactly the same as a do-nothing program:
int main() { }
[...]
are meaningless.
On Mon, 10 Feb 2025 02:44:26 +0100
Opus <ifonly@youknew.org> wrote:
On 09/02/2025 19:19, Michael S wrote:
On Sun, 9 Feb 2025 18:46:44 +0100
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
wrong! - assignment to 'a[99]' produced also no compiler
complaints,
gcc produces warning in this case, but only at optimization level
of 2 or higher.
Which version of gcc?
14.1
My test code is:
void bar(char*[]);
int foo(void)
{
int n = 10;
char *a[n];
bar(a);
a[99] = "42";
return a[3][2];
}
Tried with gcc 14.2 (x86-64) with -Wall -O3 (or -O2, same), it
doesn't give any warning whatsoever. (And yes, same with clang.)
May be, in your test arr[] is not used later, so compiler silently
optimizes away all accesses?
On Sat 2/8/2025 11:50 PM, Janis Papanagnou wrote:
I've found examples on the Net where the arrays have been defined
in a function context and the size passed as parameter
f(int n) {
char * arr[n];
...
}
Yes, that would be a VLA.
That reminded me on other languages where you'd need at least a
block context for dynamically sized arrays, like
int n = 5;
{
char * arr[n];
...
}
But a function body is in itself a block. Inside a function body
you are already in "a block context".
Anyway. I tried it without function or block context
int n = 5;
char * arr[n];
...
and it seemed to work seamlessly like that (with GNU cc,
-std=C99).
You mean you did this at file scope? No, VLAs are illegal at file
scope. And I was unable to repeat this feat in GCC.
Q1: Is this a correct (portable) form?
VLA objects have to be declared locally. However, keep in mind
that support for local declarations of VLA _objects_ is now
optional (i.e. not portable). Support for variably-modified
_types_ themselves (VLA types) is mandatory. But you are not
guaranteed to be able to declare an actual VLA variable.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (0 / 16) |
Uptime: | 165:56:24 |
Calls: | 10,385 |
Calls today: | 2 |
Files: | 14,057 |
Messages: | 6,416,528 |