static in [ ]

P

pemo

Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

And, this is an illgal prototype?

void someFunc(char a[static]);

Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Also,

void someOtherFunc(char a[static]) {} - no size, this is illegal?

void anotherFunc(char a[static *]); - illegal prototype?
 
S

serrand

pemo said:
Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

And, this is an illgal prototype?

void someFunc(char a[static]);

Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Also,

void someOtherFunc(char a[static]) {} - no size, this is illegal?

void anotherFunc(char a[static *]); - illegal prototype?

static is a storage class qualifier : you must give some definition...
I'm not sure but 10, as any litterals are by definition static...
if one could say so...

may be you wanted to specify static char a[];
.... which can't be param of a function of course...

Xavier
 
S

serrand

pemo said:
Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

And, this is an illgal prototype?

void someFunc(char a[static]);

Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Also,

void someOtherFunc(char a[static]) {} - no size, this is illegal?

void anotherFunc(char a[static *]); - illegal prototype?

You can write
void someFunc3(int b, char a[static b]){}
but it seems redundant...

b act as a const in array definition in callee,
b, as a variable may have any int value fro call to call...
as a parameter it exists when your function is invocated

Xavier
 
M

mdlinux7

Please tell me which compiler you are using ?
When I try to do something like this
void someFunc(int b , char a[static 10]){ }

I get a compilation error in VC++6.0 compiler.

The 'static' says that a[] will not >be a NULL pointer, and will
always
*[at-least/at-most?]* 10 >elements.

Where this has been mentioned in C Standards?

Regards
Dinesh
 
J

John Bode

pemo said:
Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

Wow. I was about to post a very long and detailed explanation of why
that's wrong, but now I see that's a C99-ism. Based on what I've read
so far and the limited experimentation I've done in gcc (which isn't
fully C99-compliant), that looks right; the pointer a will indeed be
non-NULL, and the actual array a points to will contain *exactly* 10
elements of char.

Guess I should have been paying more attention when C99 was being
developed; not sure what I think about that particular change.
And, this is an illgal prototype?

void someFunc(char a[static]);

Based on what I've read, yes. The grammar requires that some kind of
size expression be present. gcc also bitches about it, but since it
isn't fully compliant, that's not a clear endorsement one way or the
other.
Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Well, you could replace the constant 10 with some non-constant
expression that evaluates to 10.
Also,

void someOtherFunc(char a[static]) {} - no size, this is illegal?

Based on what I've read and looking at the grammar, yes, that is
illegal.
void anotherFunc(char a[static *]); - illegal prototype?

Well, gcc didn't like it (parse error; see caveats above); based on
what I've read, the static keyword and the asterisk work at cross
purposes, so it's likely that this particular combination is indeed
illegal.
 
M

Michael Mair

John said:
pemo said:
Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

at least
Wow. I was about to post a very long and detailed explanation of why
that's wrong, but now I see that's a C99-ism. Based on what I've read
so far and the limited experimentation I've done in gcc (which isn't
fully C99-compliant), that looks right; the pointer a will indeed be
non-NULL, and the actual array a points to will contain *exactly* 10

*at least*
elements of char.

Guess I should have been paying more attention when C99 was being
developed; not sure what I think about that particular change.

- The compiler sometimes can use the respective information
to optimize the first N array operations (which may be all
you ever perform in the respective function) because you
have effectively the same situation as in
foo()
{
char a[10] = ....
....
}
- The compiler can tell you that passing NULL to somefunc()
is a Bad Idea.

And, this is an illgal prototype?

void someFunc(char a[static]);

Based on what I've read, yes. The grammar requires that some kind of
size expression be present. gcc also bitches about it, but since it
isn't fully compliant, that's not a clear endorsement one way or the
other.

Yep: 6.7.5.2 demands
D[ static type-qualifier-list_opt assignment-expression ]
D[ type-qualifier-list static assignment-expression ]
for the declarator i.e. the assignment-expression is not optional.
Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Well, you could replace the constant 10 with some non-constant
expression that evaluates to 10.

Actually, I am not sure whether
void someFunc (int size, char a[static size])
makes sense or is even legal.

Also,

void someOtherFunc(char a[static]) {} - no size, this is illegal?
Yes.
void anotherFunc(char a[static *]); - illegal prototype?

Yes.


Cheers
Michael
 
J

John Bode

Michael said:
John Bode schrieb:
[snip]
Wow. I was about to post a very long and detailed explanation of why
that's wrong, but now I see that's a C99-ism. Based on what I've read
so far and the limited experimentation I've done in gcc (which isn't
fully C99-compliant), that looks right; the pointer a will indeed be
non-NULL, and the actual array a points to will contain *exactly* 10

*at least*

Ah. Thanks.
elements of char.

Guess I should have been paying more attention when C99 was being
developed; not sure what I think about that particular change.

- The compiler sometimes can use the respective information
to optimize the first N array operations (which may be all
you ever perform in the respective function) because you
have effectively the same situation as in
foo()
{
char a[10] = ....
....
}
- The compiler can tell you that passing NULL to somefunc()
is a Bad Idea.

I understand that, it's just that at first blush it seems to further
muddy the waters when it comes to passing arrays as function arguments;
it makes it look more like the actual argument is an array type instead
of a pointer type.

The reasoning behind the change makes sense, it just reads a little
funny.
 
G

Guest

Michael said:
Actually, I am not sure whether
void someFunc (int size, char a[static size])
makes sense or is even legal.

I'm curious about that. My understanding was that all array parameters
are silently changed to pointer parameters, regardless of whether the
size is constant, so that

void someFunc (int size, char a[size])

acts simply as

void someFunc (int size, char *a)

and passing a pointer to fewer than size characters is fine. If this is
really the case (if it isn't, please correct me, because it does seem a
bit weird), "static size" would make perfect sense here.
 
J

Jack Klein

Michael said:
Actually, I am not sure whether
void someFunc (int size, char a[static size])
makes sense or is even legal.

I'm curious about that. My understanding was that all array parameters
are silently changed to pointer parameters, regardless of whether the
size is constant, so that

void someFunc (int size, char a[size])

acts simply as

void someFunc (int size, char *a)

and passing a pointer to fewer than size characters is fine. If this is
really the case (if it isn't, please correct me, because it does seem a
bit weird), "static size" would make perfect sense here.

This syntax is defined by the C standard to allow compilers to perform
certain optimizations on hardware platforms that support them.

Let's take an example prototype:

return_type function_name(int a[static 256]);

The argument 'a' is indeed a pointer to int inside the function, but
this new prototype style tells the compiler that the function will
_always_ be called with 'a' pointing to at least 256 consecutive ints.
This allows the compiler to generate prefetch or cache instructions on
processors, vector units, and DSPs that have hardware support for
this, and can make accessing the elements of the array faster in the
function's body.

Given the prototype above, this:

void somefunc(void)
{
int array [128] = { 0 );
function_name(array);
}

....produces undefined behavior, even if the function body itself never
accesses more than 128 members of the array, because the prefetch
mechanism, if it exists and is invoked, might access memory past the
end of the array.
 
M

Michael Mair

Harald said:
Michael said:
Actually, I am not sure whether
void someFunc (int size, char a[static size])
makes sense or is even legal.

I'm curious about that. My understanding was that all array parameters
are silently changed to pointer parameters, regardless of whether the
size is constant, so that

void someFunc (int size, char a[size])

acts simply as

void someFunc (int size, char *a)

and passing a pointer to fewer than size characters is fine. If this is
really the case (if it isn't, please correct me, because it does seem a
bit weird), "static size" would make perfect sense here.

I do not think so:

Maybe to wrap it up:
Usually, VLA parameters make only sense if you need pointer
arithmetics, i.e. for
void someFunc (int size, char (*a)[size])
you have real benefit from specifying the parameter this way.
The benefit of static in such a case
void someFunc (int size, char a[static 1][size])
in turn is that "a" definitely is no NULL pointer.
However, if we have "a[static size][1]", we have not gained
anything, as we cannot make any compile time assumptions --
size might always be >=1700 but there is no way the compiler
can know that without very extensive, expensive and
error-prone analysis.

About my above statement: I have not chased down what
"assignment-expression" means in terms of the standard; even
though it might make sense to combine VLAs and static directly
(which I do not see at the moment), it may be forbidden by
the wording.


Cheers
Michael
 
M

Micah Cowan

pemo said:
Could someone tell me if I have this right please?

Given this definition:

void someFunc(char a[static 10]){}

The 'static' says that a[] will not be a NULL pointer, and will always
*[at-least/at-most?]* 10 elements.

at least 10, but you're missing the verb. The full sentence is: a will
be a pointer to the first element in an array of at /least/ 10 chars.
And, this is an illgal prototype?

void someFunc(char a[static]);

Yes, it's illegal: there must be an expression following
"static". Plus, without an expression following it, the "static"
keyword here is completely useless; it's whole purpose is to guarantee
that the array being passed via a pointer to its first element is at
least such-and-such elements in size.
Would the *only* legal prototype be:

void someFunc(char a[static 10]);

Well, obviously not; ... a[static 11] would certainly be legal...

Other than that, it's worth noting that you can also put type
qualifiers in there, such as:

void someFunc(char a[const static 10]);

Which is identical to

void someFunc(char * const a);

except for the added assurance that the "static 10" part
provides. That is, it declares a to be a const pointer to char that
points to the first element of an array with at least 10 elements.
void someOtherFunc(char a[static]) {} - no size, this is illegal?

void anotherFunc(char a[static *]); - illegal prototype?

These are both illegal (syntactically invalid).
==============
Not a pedant
==============

Mm. Sorry to hear it. :)
 
G

Guest

Michael said:
Harald said:
Michael said:
Actually, I am not sure whether
void someFunc (int size, char a[static size])
makes sense or is even legal.

I'm curious about that. My understanding was that all array parameters
are silently changed to pointer parameters, regardless of whether the
size is constant, so that

void someFunc (int size, char a[size])

acts simply as

void someFunc (int size, char *a)

and passing a pointer to fewer than size characters is fine. If this is
really the case (if it isn't, please correct me, because it does seem a
bit weird), "static size" would make perfect sense here.

I do not think so:

Maybe to wrap it up:
Usually, VLA parameters make only sense if you need pointer
arithmetics, i.e. for
void someFunc (int size, char (*a)[size])
you have real benefit from specifying the parameter this way.
The benefit of static in such a case
void someFunc (int size, char a[static 1][size])
in turn is that "a" definitely is no NULL pointer.
However, if we have "a[static size][1]", we have not gained
anything, as we cannot make any compile time assumptions --
size might always be >=1700 but there is no way the compiler
can know that without very extensive, expensive and
error-prone analysis.

As one example, the compiler can assume that for i+1<size, a[i+1] is
accessible, and use this to change an expensive assignment to a to a
cheap one that sets both a and a[i+1], and then restore a[i+1]. If
the function contains a simple for loop which may exit early, I don't
think it's unreasonable for the compiler to do this. (If the function
contains a simple for loop which can't exit early, I don't think it's
unreasonable for the compiler to do this even without "static".) Do you
think that is an unrealistic example?
About my above statement: I have not chased down what
"assignment-expression" means in terms of the standard;

Simply put, any expression without an unparenthesised , operator.
even
though it might make sense to combine VLAs and static directly
(which I do not see at the moment), it may be forbidden by
the wording.

I'm reading from http://c0x.coding-guidelines.com/6.7.5.3.html right
now, and I don't see any distinction between constant and non-constant
sizes as far as static is concerned, but if I'm missing something there
or somewhere else, let me know.
 

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
474,175
Messages
2,570,944
Members
47,492
Latest member
gabbywilliam

Latest Threads

Top