array declarators

B

borophyll

I have two questions. The first: does the declaration of an array
parameter in a function prototype which uses the [*] notation mean
that the array must be a variable length array. That is, the
following code won't work:

int foo(int a[*]);

int foo(int a[])
{
return a[0];
}

and neither will the following:

int foo(int a[*]);

int foo(int a[6])
{
return a[0];
}

since neither are variable length arrays. Can someone confirm or deny
this? I can't test it myself as gcc doesn't implement this syntax
yet...

Second question: what effect does the static keyword have on array
declarators? For instance:

int foo(int a[static 6]) {...}

I have read and reread the spec on this matter, but do not understand
the semantics. Perhaps an example of its usage pls?

Regards,
B.
 
B

borophyll

I have two questions. The first: does the declaration of an array
parameter in a function prototype which uses the [*] notation mean
that the array must be a variable length array. That is, the
following code won't work:

int foo(int a[*]);

int foo(int a[])
{
return a[0];

}

and neither will the following:

int foo(int a[*]);

int foo(int a[6])
{
return a[0];

}

since neither are variable length arrays. Can someone confirm or deny
this? I can't test it myself as gcc doesn't implement this syntax
yet...

Second question: what effect does the static keyword have on array
declarators? For instance:

int foo(int a[static 6]) {...}

I have read and reread the spec on this matter, but do not understand
the semantics. Perhaps an example of its usage pls?

Regards,
B.

Hold on, I think I understand the second part now. Does static mean
that array a must be at least 6 elements in length, but can possibly
be more. Hence the static keyword allows you to access array elements
whose index exceeds 5 without the compiler complaining...
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

I have two questions. The first: does the declaration of an array
parameter in a function prototype which uses the [*] notation mean that
the array must be a variable length array. That is, the following code
won't work:

int foo(int a[*]);

int foo(int a[])
{
return a[0];

}

It will.
and neither will the following:

int foo(int a[*]);

int foo(int a[6])
{
return a[0];

}

This will also work.

Your function has a single parameter of type pointer to int. There is no
array. And even if arrays get involved:

int foo(int (*a)[*]);
int foo(int (*a)[6]) {
/* ... */
}

I believe this is allowed. The [*] means that it's a VLA, and a VLA is
compatible with any non-VLA array. The programmer is responsible for
ensuring the sizes match up, and here, since * doesn't actually specify a
size, there's no problem.
Second question: what effect does the static keyword have on array
declarators? For instance:

int foo(int a[static 6]) {...}

I have read and reread the spec on this matter, but do not understand
the semantics. Perhaps an example of its usage pls?

Regards,
B.

Hold on, I think I understand the second part now. Does static mean
that array a must be at least 6 elements in length, but can possibly be
more.
Yes.

Hence the static keyword allows you to access array elements
whose index exceeds 5 without the compiler complaining...

I don't understand what you mean. You are allowed to access a[0] through a
[10] if a points to 11 ints, with or without the static keyword. The
static keyword means that even if foo only access a[0], if there aren't
at least 5 ints following it, the behaviour is undefined. It allows for
certain optimisations that would otherwise be invalid, but nothing more.
 
B

borophyll

I have two questions. The first: does the declaration of an array
parameter in a function prototype which uses the [*] notation mean that
the array must be a variable length array. That is, the following code
won't work:
int foo(int a[*]);
int foo(int a[])
{
return a[0];
}

It will.
and neither will the following:
int foo(int a[*]);
int foo(int a[6])
{
return a[0];
}

This will also work.

Your function has a single parameter of type pointer to int. There is no
array. And even if arrays get involved:

int foo(int (*a)[*]);
int foo(int (*a)[6]) {
/* ... */

}

I believe this is allowed. The [*] means that it's a VLA, and a VLA is
compatible with any non-VLA array. The programmer is responsible for
ensuring the sizes match up, and here, since * doesn't actually specify a
size, there's no problem.
Second question: what effect does the static keyword have on array
declarators? For instance:
int foo(int a[static 6]) {...}
I have read and reread the spec on this matter, but do not understand
the semantics. Perhaps an example of its usage pls?
Regards,
B.
Hold on, I think I understand the second part now. Does static mean
that array a must be at least 6 elements in length, but can possibly be
more.
Yes.

Hence the static keyword allows you to access array elements
whose index exceeds 5 without the compiler complaining...

I don't understand what you mean. You are allowed to access a[0] through a
[10] if a points to 11 ints, with or without the static keyword. The
static keyword means that even if foo only access a[0], if there aren't
at least 5 ints following it, the behaviour is undefined. It allows for
certain optimisations that would otherwise be invalid, but nothing more.

So, from the point of view of the abstract machine, the static keyword
in this context has no effect?
 
J

Jack Klein

On Sep 23, 9:10 pm, (e-mail address removed) wrote:
I have two questions. The first: does the declaration of an array
parameter in a function prototype which uses the [*] notation mean that
the array must be a variable length array. That is, the following code
won't work:
int foo(int a[*]);
int foo(int a[])
{
return a[0];

It will.
and neither will the following:
int foo(int a[*]);
int foo(int a[6])
{
return a[0];

This will also work.
since neither are variable length arrays. Can someone confirm or deny
this? I can't test it myself as gcc doesn't implement this syntax
yet...

Your function has a single parameter of type pointer to int. There is no
array. And even if arrays get involved:

int foo(int (*a)[*]);
int foo(int (*a)[6]) {
/* ... */

}

I believe this is allowed. The [*] means that it's a VLA, and a VLA is
compatible with any non-VLA array. The programmer is responsible for
ensuring the sizes match up, and here, since * doesn't actually specify a
size, there's no problem.
Second question: what effect does the static keyword have on array
declarators? For instance:
int foo(int a[static 6]) {...}
I have read and reread the spec on this matter, but do not understand
the semantics. Perhaps an example of its usage pls?

Hold on, I think I understand the second part now. Does static mean
that array a must be at least 6 elements in length, but can possibly be
more.
Yes.

Hence the static keyword allows you to access array elements
whose index exceeds 5 without the compiler complaining...

I don't understand what you mean. You are allowed to access a[0] through a
[10] if a points to 11 ints, with or without the static keyword. The
static keyword means that even if foo only access a[0], if there aren't
at least 5 ints following it, the behaviour is undefined. It allows for
certain optimisations that would otherwise be invalid, but nothing more.

So, from the point of view of the abstract machine, the static keyword
in this context has no effect?

I would not agree with that statement. By defining a function:

int foo(int a[static 6]) { return 0; }

....you are giving the compiler explicit permission to access the ints
at a[0] through a[5], before any declarations or code in the body of
the function are executed.

If you remove the static keyword and pass the function above a null
pointer, the behavior is strictly defined and foo() returns 0.

With the static keyword as used, if you pass the function a null
pointer, the behavior is undefined.

With the static keyword, passing a null pointer produces undefined
behavior even if the body of the function never access any of the data
pointed to. Without it, passing a null pointer does not produce
undefined data unless the pointer is dereferenced.

So it would be better to consider the meaning of such a declaration to
the abstract machine something like this:

int foo(int a [static 6])
{
int compiler_temp[6];
memcpy(compiler_temp, a, 6 * sizeof *a);
/* user declarations and code */
return 0;
}

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

10 pm, (e-mail address removed) wrote:
int foo(int a[static 6]) {...}

Hence the static keyword allows you to access array elements whose
index exceeds 5 without the compiler complaining...

I don't understand what you mean. You are allowed to access a[0]
through a [10] if a points to 11 ints, with or without the static
keyword. The static keyword means that even if foo only access a[0],
if there aren't at least 5 ints following it, the behaviour is
undefined. It allows for certain optimisations that would otherwise
be invalid, but nothing more.

So, from the point of view of the abstract machine, the static keyword
in this context has no effect?

I would not agree with that statement.

I would, personally.
By defining a function:

int foo(int a[static 6]) { return 0; }

...you are giving the compiler explicit permission to access the ints at
a[0] through a[5], before any declarations or code in the body of the
function are executed.

If you remove the static keyword and pass the function above a null
pointer, the behavior is strictly defined and foo() returns 0.

With the static keyword as used, if you pass the function a null
pointer, the behavior is undefined.

With the static keyword, passing a null pointer produces undefined
behavior even if the body of the function never access any of the data
pointed to. Without it, passing a null pointer does not produce
undefined data unless the pointer is dereferenced.

No disagreements here.
So it would be better to consider the meaning of such a declaration to
the abstract machine something like this:

int foo(int a [static 6])
{
int compiler_temp[6];
memcpy(compiler_temp, a, 6 * sizeof *a); /* user declarations and
code */
return 0;
}

I would consider it as "from the point of view of the abstract machine,
the static keyword in this context has no effect; however, the behaviour
is undefined, so an implementation is not required to make the actual
behaviour match that of the abstract machine".

(I'm just arguing over wording, though. As far as permission to
implementation goes, I think I agree with your view.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top