Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

static keyword in array declarations

9 views
Skip to first unread message

jacob navia

unread,
Sep 22, 2001, 1:37:22 PM9/22/01
to
In the new standard (C99) it is mentioned that the keyword "static" can
appear in an array declaration
int a[static ...]

Can anyone here explain in normal words (I can barely follow the legalese
English) what actually this keyword is supposed to do?

Thanks in advance

P.S. As far as I understood it, this should happen only in parameter
declarations, is that right?

--
---
Jacob Navia Logiciels/informatique
41 rue Maurice Ravel
93430 Villetaneuse
France


Nick Maclaren

unread,
Sep 22, 2001, 2:09:01 PM9/22/01
to
In article <9oii8f$pgn$1...@wanadoo.fr>,

jacob navia <ja...@jacob.remcomp.fr> wrote:
>In the new standard (C99) it is mentioned that the keyword "static" can
>appear in an array declaration
>int a[static ...]
>
>Can anyone here explain in normal words (I can barely follow the legalese
>English) what actually this keyword is supposed to do?

Yes. It is intended to say that the declaration is using the same
semantics as Fortran 77. I.e. that the actual argument will be a
real array (i.e. not NULL) and at least as long as the size given
in the parameter.

>P.S. As far as I understood it, this should happen only in parameter
>declarations, is that right?

That was the intent, and I believe is the situation.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679

Jack Klein

unread,
Sep 22, 2001, 5:02:34 PM9/22/01
to
On Sat, 22 Sep 2001 19:37:22 +0200, "jacob navia"
<ja...@jacob.remcomp.fr> wrote in comp.std.c:

> In the new standard (C99) it is mentioned that the keyword "static" can
> appear in an array declaration
> int a[static ...]
>
> Can anyone here explain in normal words (I can barely follow the legalese
> English) what actually this keyword is supposed to do?
>
> Thanks in advance
>
> P.S. As far as I understood it, this should happen only in parameter
> declarations, is that right?

To add to what Nick said, the purpose is to allow the use of data
pre-fetch instructions that some DSP and RISC and even some CISC
processors now have. The generated code for a function that receives
such an array as a parameter can include a pre-fetch instruction to
move the contents of the array into a cache or other fast access
buffer before they are needed.

If the pointer does not actually point to the specified amount of data
legally accessible to the program, the behavior is undefined and
indeed such a pre-fetch instruction might fail if the pointer is
invalid.

A compiler may completely ignore this keyword and take no action, just
as it may for the restrict keyword. Its presence does not change the
meaning of any strictly conforming program.

--
Jack Klein
Home: http://JK-Technology.Com

jacob navia

unread,
Sep 23, 2001, 11:53:55 AM9/23/01
to
OK, Thanks for this clarifications.

What I personally do not like in this is that the meaning of "static" has
NOTHING to do with the semantics involved, i.e. it is surely NOT implying
that the array is in the static storage area!

Why misuse "static"?

I am programming C for at least 20 years, and I was confused by this. I can
imagine what newbies will say...

jacob navia

unread,
Sep 23, 2001, 12:10:43 PM9/23/01
to

"Jack Klein" <jack...@spamcop.net> wrote in message
news:ivupqtohucjt4lr49...@4ax.com...

>
> To add to what Nick said, the purpose is to allow the use of data
> pre-fetch instructions that some DSP and RISC and even some CISC
> processors now have. The generated code for a function that receives
> such an array as a parameter can include a pre-fetch instruction to
> move the contents of the array into a cache or other fast access
> buffer before they are needed.
>
The problem with those instructions is that
1. They take code space, making the program larger.
2. It is quite difficult to determine when and how to do that prefetching.

Leaving aside point 2, the speed delta between a P4 processor running at
1500MHZ and RAM running about 20MHZ is now SO GREAT, that if the reading of
those extra bytes for the prefetch instruction happens to be at the
beginning of a 32 byte cache entry, so that the whole cache line would have
to be brought into the L1 cache this would result in a big time loss. A
1.5GHZ P4 has to put A LOT of wait cycles what would be a much bigger loss
than the positive effects those prefetch instruction would achieve anyway.

> If the pointer does not actually point to the specified amount of data
> legally accessible to the program, the behavior is undefined and
> indeed such a pre-fetch instruction might fail if the pointer is
> invalid.

Yes, a TRAP. How nasty :-)

>
> A compiler may completely ignore this keyword and take no action

I think this is what I will do for lcc-win32. Anyway, if this kind of
declaration appears outside a parameter scope I will put an error message,
meaning that compilation will fail.


Peter Seebach

unread,
Sep 23, 2001, 2:02:06 PM9/23/01
to
In article <9ol0ii$ea3$1...@wanadoo.fr>,

jacob navia <ja...@jacob.remcomp.fr> wrote:
>What I personally do not like in this is that the meaning of "static" has
>NOTHING to do with the semantics involved, i.e. it is surely NOT implying
>that the array is in the static storage area!

That's okay, that's not what "static" means.

>Why misuse "static"?

Because it was already a keyword, and it couldn't mean much else in that
context. And, of course, because it's not a C standard without a new use
for "static".

Sometimes static means "don't advertise this name". Sometimes it means "make
this permanent". And now, sometimes, it means "this really does exist and
have this size".

They all sound similar to me.

-s
--
Copyright 2001, all wrongs reversed. Peter Seebach / se...@plethora.net
$ chmod a+x /bin/laden Please do not feed or harbor the terrorists.
C/Unix wizard, Pro-commerce radical, Spam fighter. Boycott Spamazon!
Consulting, computers, web hosting, and shell access: http://www.plethora.net/

jacob navia

unread,
Sep 23, 2001, 4:45:57 PM9/23/01
to

"Peter Seebach" <se...@plethora.net> wrote in message
news:3bae239e$0$320$3c09...@news.plethora.net...

> In article <9ol0ii$ea3$1...@wanadoo.fr>,
> jacob navia <ja...@jacob.remcomp.fr> wrote:
> >What I personally do not like in this is that the meaning of "static" has
> >NOTHING to do with the semantics involved, i.e. it is surely NOT implying
> >that the array is in the static storage area!
>
> That's okay, that's not what "static" means.

I am sorry, I have misunderstood C then. I thought, it meant that there
should be a common storage area, for unnamed objects, that can be either
code (machine instructions) or data.

Within each compilation unit, there is only two things: code (machine
instructions) and data: (reserved space and literals).
The static keyword can be used for code, meaning that this code isn't
visible from outside, and belongs to the unnamed code section. Or it can be
used for data, meaning the storage is in an unnamed module specific area.
This area can be accessed locally of course, using symbolic variable names:
you can call a static function, and use a static identifier within that
unit.

I thought I grasped that, sometime ago, but there is always a new twist in
C, and I would be glad to know where I could be wrong actually.

Obviously, as you point out, there can't be a new C standard without a new
meaning for this static keyword. This is considered as an economy of
keywords by some people, but I tend to consider this as just confusing.

A new keyword, that can appear only in a specific context is quite cheap. I
mean is just several bytes of storage in the compiler for storing and
recognizing that keyword.

This new semantics (i.e. allowing the programmer to specify a minimum size
for an incoming array parameters) should be signified with a new keyword
that only is accepted after '['. Not very difficult, and it would make the
intention of the programmer clearer. I do not understand why we should limit
this to parameter declarations either. There is NO reason. It is always
better to be able to pass more specific information to the compiler.

We should consider in this dicussion, that the fundamental bug source in C
is buffer overflow and pointer misusage. Allowing the programmer to define
the size of an array in a general way would be quite a change. Buffer
overflow exploits are plaguing the language with bugs that could be easily
catched with automatic index checking. NIMDA would not exist.

I have recently introduced garbage collection in my compiler system, and I
feel glad to forget about free() and all the associated boring accounting of
each byte. Index checking would be nice to have too. I am getting fed up
with those eternal pointer overflows. Why not letting the machine check
those indexes automatically?

I mean we have so much computer power available today at our fingertips,
that sticking to old-fashioned "efficiency" considerations is completely
wrong. Modern processors run in the GHZ range (entry-models), and checking
an index in an array is something you wouldn't notice in most applications.
Of course it can be a compiler switch, that can be turned off in certain
applications that require it.

But that's another discussion. Coming back to "static", I think the reasons
of "static" being cherished, is that it avoids name conflicts with existing
user identifiers. Since identifiers starting with an underscore have been
reserved for the compiler since quite a time, we should device an escape
sequence for introducing new keywords as C evolves. For instance a clear
name like:

_at_least.

and a declaration of intention forbidding strictly the usage of "_" as
starting char in user identifiers would be a much clearer decision. The
standard reserves "_" as introducing future keywords.

C will evolve, and we should acknowledge this fact instead of reusing old
keywords with new meanings, a bad practice.
.


Marcin 'Qrczak' Kowalczyk

unread,
Sep 23, 2001, 5:15:57 PM9/23/01
to
Sun, 23 Sep 2001 22:45:57 +0200, jacob navia <ja...@jacob.remcomp.fr> pisze:

> Since identifiers starting with an underscore have been reserved
> for the compiler since quite a time, we should device an escape
> sequence for introducing new keywords as C evolves. For instance
> a clear name like:
>
> _at_least.

I think >= could be used there instead.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Peter Seebach

unread,
Sep 23, 2001, 5:39:07 PM9/23/01
to
In article <9olhm7$jtb$1...@wanadoo.fr>,

jacob navia <ja...@jacob.remcomp.fr> wrote:
>"Peter Seebach" <se...@plethora.net> wrote in message
>news:3bae239e$0$320$3c09...@news.plethora.net...
>> In article <9ol0ii$ea3$1...@wanadoo.fr>,
>> jacob navia <ja...@jacob.remcomp.fr> wrote:
>> >What I personally do not like in this is that the meaning of "static" has
>> >NOTHING to do with the semantics involved, i.e. it is surely NOT implying
>> >that the array is in the static storage area!

>> That's okay, that's not what "static" means.

>I am sorry, I have misunderstood C then. I thought, it meant that there
>should be a common storage area, for unnamed objects, that can be either
>code (machine instructions) or data.

No, not at all. Functions declared "static" are not in a special area;
they just aren't visible to the linker. That's it.

>The static keyword can be used for code, meaning that this code isn't
>visible from outside, and belongs to the unnamed code section.

There's nothing anywhere saying that this is a special "section" or anything
like that.

>Or it can be
>used for data, meaning the storage is in an unnamed module specific area.

That doesn't make any sense. "static" data is available globally - it's just
only *named* wherever you declared it. Similarly, if you have a static
function, that *name* is not visible in other modules - but you could take
the address of that function and other modules could call it.

>I thought I grasped that, sometime ago, but there is always a new twist in
>C, and I would be glad to know where I could be wrong actually.

Okay, here's the easy way to think of it:

* If you declare an object that isn't inside a function "static", you are
saying "do not export this symbol's name to other modules". That's all.
* If you declare an object that *is* inside a function "static", you are
saying "allocate permanent storage for this, and only initialize it once".
That's all.

>I have recently introduced garbage collection in my compiler system, and I
>feel glad to forget about free() and all the associated boring accounting of
>each byte. Index checking would be nice to have too. I am getting fed up
>with those eternal pointer overflows. Why not letting the machine check
>those indexes automatically?

It's allowed to, but it's sometimes undesirable.

>I mean we have so much computer power available today at our fingertips,
>that sticking to old-fashioned "efficiency" considerations is completely
>wrong.

No, it isn't. There is an active community that uses features like this;
it was added to the language *because people were already using such a
feature*.

Robert Corbett

unread,
Sep 23, 2001, 9:37:07 PM9/23/01
to
In article <9oik3t$ptb$1...@pegasus.csx.cam.ac.uk>,

Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
>In article <9oii8f$pgn$1...@wanadoo.fr>,
>jacob navia <ja...@jacob.remcomp.fr> wrote:
>>In the new standard (C99) it is mentioned that the keyword "static" can
>>appear in an array declaration
>>int a[static ...]
>>
>>Can anyone here explain in normal words (I can barely follow the legalese
>>English) what actually this keyword is supposed to do?
>
>Yes. It is intended to say that the declaration is using the same
>semantics as Fortran 77. I.e. that the actual argument will be a
>real array (i.e. not NULL) and at least as long as the size given
>in the parameter.

I can believe that was the intent. The more I read the relevant
sections of the C99 standard, the less certain I am what they say.

In Fortran, the size of an explicit-shape array used as a formal
parameter must be less than or equal to the size of any array
used as the corresponding actual parameter. The ranks of the
arrays are not required to match, and the bounds in any given
dimension are not required to match. For example, in Fortran
the array

REAL A(4, 4)

could be passed as an actual parameters to formal arrays
declared as

REAL B(16)

REAL B(8, 2), or

REAL B(2, 2, 2, 2).

The C standard at first seems to be saying something analogous.
The one-dimensional cases seem to work. An array a defined as

float a[16];

could be passed to a formal parameter b declared as

float b[static 16]

I find the multi-dimensional cases less clear. For example,
could the array a be passed to a formal parameter c declared as

float c[static 4][4]?

Could an array d defined as

float d[4][4];

be passed to the formal parameter b?

Sincerely,
Bob Corbett

James Russell Kuyper Jr.

unread,
Sep 23, 2001, 10:59:14 PM9/23/01
to
Robert Corbett wrote:
...

> The C standard at first seems to be saying something analogous.
> The one-dimensional cases seem to work. An array a defined as
>
> float a[16];
>
> could be passed to a formal parameter b declared as
>
> float b[static 16]
>
> I find the multi-dimensional cases less clear. For example,
> could the array a be passed to a formal parameter c declared as
>
> float c[static 4][4]?

No. As an argument, 'a' would decay to 'float *', while the type of c is
'float(*)[4]'. The types don't match. The 'static' merely imposes an
additional requirement on the caller; it does nothing to change the
actual types.

> Could an array d defined as
>
> float d[4][4];
>
> be passed to the formal parameter b?

No. "float b[static 16]" is equivalent to "float *b", with the added
restriction that the array pointed at must have at least 16 elements.
'd' decays into a float (*)[4] when passed as a function argument, which
is not compatible "float *".

Now, d[0] would have the correct type, but it refers to an array with
only 4 elements, so it's still wrong. There's 12 additional float
objects just after those 4 elements, but you can't legally access them
using d[0]. The largest offset you can add to d[0] is 4; you can't add
more than 3 and still have a derefenceable pointer. As a practical
mater, on most implementations I've ever used it would work perfectly.
However, because it's illegal to access those elements through that
pointer, an implementation is free to implement run-time bounds checking
that will make your program abort if you actually try it.

Colm Mac Cárthaigh

unread,
Sep 24, 2001, 1:02:41 AM9/24/01
to
On Sun, 23 Sep 2001 22:45:57 +0200, <ja...@jacob.remcomp.fr> wrote:
> A new keyword, that can appear only in a specific context is quite cheap. I
> mean is just several bytes of storage in the compiler for storing and
> recognizing that keyword.

and what of the potentially thousands of sources that
use that keyword as a symbol ?

--
------------------------------------------------------------
colm...@redbrick.dcu.ie

(master of the web, apache warrior)

jacob navia

unread,
Sep 24, 2001, 1:56:14 AM9/24/01
to

"Colm Mac Cárthaigh " <colm...@RedBrick.DCU.IE> wrote in message
news:slrn9qteie....@Enigma.RedBrick.DCU.IE...

> On Sun, 23 Sep 2001 22:45:57 +0200, <ja...@jacob.remcomp.fr> wrote:
> > A new keyword, that can appear only in a specific context is quite
cheap. I
> > mean is just several bytes of storage in the compiler for storing and
> > recognizing that keyword.
>
> and what of the potentially thousands of sources that
> use that keyword as a symbol ?

Identifiers starting with "_" are forbidden in user programs.
This is the same problem as in the _Complex keyword sorry. If you had used
_Complex before in your programs, C99 destroyed your programs. But it would
be YOUR fault since all identifiers starting with "_" are reserved.

Nick Maclaren

unread,
Sep 24, 2001, 6:43:57 AM9/24/01
to

In article <9ol1i1$ofe$1...@wanadoo.fr>,

"jacob navia" <ja...@jacob.remcomp.fr> writes:
|> "Jack Klein" <jack...@spamcop.net> wrote in message
|> news:ivupqtohucjt4lr49...@4ax.com...
|> >
|> > To add to what Nick said, the purpose is to allow the use of data
|> > pre-fetch instructions that some DSP and RISC and even some CISC
|> > processors now have. The generated code for a function that receives
|> > such an array as a parameter can include a pre-fetch instruction to
|> > move the contents of the array into a cache or other fast access
|> > buffer before they are needed.
|> >
|> The problem with those instructions is that
|> 1. They take code space, making the program larger.
|> 2. It is quite difficult to determine when and how to do that prefetching.
|>
|> Leaving aside point 2, the speed delta between a P4 processor running at
|> 1500MHZ and RAM running about 20MHZ is now SO GREAT, that if the reading of
|> those extra bytes for the prefetch instruction happens to be at the
|> beginning of a 32 byte cache entry, so that the whole cache line would have
|> to be brought into the L1 cache this would result in a big time loss. A
|> 1.5GHZ P4 has to put A LOT of wait cycles what would be a much bigger loss
|> than the positive effects those prefetch instruction would achieve anyway.

No, that is the CONVERSE of the situation, as has been shown by
systems like the Hitachi SR2201! The advantages of preloading are
(a) that there is one cache access rather than several and more
importantly (b) that the loading can be done asynchronously. It
can increase the speed of many functions considerably.

Niklas Matthies

unread,
Sep 24, 2001, 12:46:59 PM9/24/01
to

This is inaccurate (not to say incorrect). Identifiers starting with
underscore and either a lowercase letter or a digit are _not_ reserved
in non-file scope and as macro names.
It doesn't invalidate your general point, though.

-- Niklas Matthies
--
No question is too silly to ask, but, of course, some are too silly to
answer. -- Perl book

Niklas Matthies

unread,
Sep 24, 2001, 12:51:40 PM9/24/01
to

I actually wonder why this new C99 feature is only available in function
prototypes. Wouldn't it be generally useful to be able to qualify a
pointer such that the implementation is allowed to rely on the first N
elements pointed to to be present?

-- Niklas Matthies
--
Who we are and who we become depends, in part, on who we love.

Nick Maclaren

unread,
Sep 24, 2001, 1:02:08 PM9/24/01
to

In article <9om2o3$ovn$1...@engnews1.eng.sun.com>,

cor...@lupa.Sun.COM (Robert Corbett) writes:
|>
|> >>In the new standard (C99) it is mentioned that the keyword "static" can
|> >>appear in an array declaration
|> >>int a[static ...]
|> >>
|> >>Can anyone here explain in normal words (I can barely follow the legalese
|> >>English) what actually this keyword is supposed to do?
|> >
|> >Yes. It is intended to say that the declaration is using the same
|> >semantics as Fortran 77. I.e. that the actual argument will be a
|> >real array (i.e. not NULL) and at least as long as the size given
|> >in the parameter.
|>
|> I can believe that was the intent. The more I read the relevant
|> sections of the C99 standard, the less certain I am what they say.
|>
|> In Fortran, the size of an explicit-shape array used as a formal
|> parameter must be less than or equal to the size of any array
|> used as the corresponding actual parameter. The ranks of the
|> arrays are not required to match, and the bounds in any given
|> dimension are not required to match. For example, in Fortran
|> the array
|>
|> REAL A(4, 4)
|>
|> could be passed as an actual parameters to formal arrays
|> declared as
|>
|> REAL B(16)
|>
|> REAL B(8, 2), or
|>
|> REAL B(2, 2, 2, 2).

That wasn't too bad in Fortran 77, but consider Fortran 90:

subroutine fred (a)
integer a(30)
do i = 1,30
a(i) = 2
end do
end

integer a(5,5,5)
do i = 1,5
do j = 1,5
do k = 1,5
a(i,j,k) = 1
end do
end do
end do
call fred(a(1:4,1:4,1:4))
do i = 1,5
write (*,'(1x,5(2x,5i2))') ((a(i,j,k), k = 1,5), j = 1,5)
end do
end

NAG 'f90 -C=all' seems to agree it is legal, and that is as paranoid
a Fortran 90 compiler as you are likely to come across.

|> The C standard at first seems to be saying something analogous.
|> The one-dimensional cases seem to work. An array a defined as
|>
|> float a[16];
|>
|> could be passed to a formal parameter b declared as
|>
|> float b[static 16]
|>
|> I find the multi-dimensional cases less clear. For example,
|> could the array a be passed to a formal parameter c declared as
|>
|> float c[static 4][4]?
|>
|> Could an array d defined as
|>
|> float d[4][4];
|>
|> be passed to the formal parameter b?

No, and they couldn't in C90. 'b' is 'float *', and the other
two are 'float (*)[4]'. If you cast them appropriate, I don't
see why not [*].


[*] At least, in THIS thread, I don't see why not. I have a
nasty document that I circulated to the BSI C Panel expressing
my view that the question "What is an object, really?" is at
least a hard a question as "What does separated by a sequence
point mean, really?"

Interested people are welcome to it, but don't bother unless
you have a copy of the C99 standard to hand and can follow at
least most of its gyrations.

Nick Maclaren

unread,
Sep 24, 2001, 1:04:01 PM9/24/01
to

In article <slrn9qup4s.h8.news_comp....@nightrunner.nmhq.net>,

news_comp.std.c_e...@nmhq.net (Niklas Matthies) writes:
|>
|> I actually wonder why this new C99 feature is only available in function
|> prototypes. Wouldn't it be generally useful to be able to qualify a
|> pointer such that the implementation is allowed to rely on the first N
|> elements pointed to to be present?

Yes, but consider the syntax :-(

Niklas Matthies

unread,
Sep 24, 2001, 1:55:15 PM9/24/01
to
On 24 Sep 2001 17:04:01 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
>
> In article <slrn9qup4s.h8.news_comp....@nightrunner.nmhq.net>,
> news_comp.std.c_e...@nmhq.net (Niklas Matthies) writes:
> |>
> |> I actually wonder why this new C99 feature is only available in function
> |> prototypes. Wouldn't it be generally useful to be able to qualify a
> |> pointer such that the implementation is allowed to rely on the first N
> |> elements pointed to to be present?
>
> Yes, but consider the syntax :-(

Pointer to array of static size. So what? :)

Clive D. W. Feather

unread,
Sep 24, 2001, 9:39:09 AM9/24/01
to
In article <9olhm7$jtb$1...@wanadoo.fr>, jacob navia
<ja...@jacob.remcomp.fr> writes

>A new keyword, that can appear only in a specific context is quite cheap. I
>mean is just several bytes of storage in the compiler for storing and
>recognizing that keyword.
>
>This new semantics (i.e. allowing the programmer to specify a minimum size
>for an incoming array parameters) should be signified with a new keyword
>that only is accepted after '['.

Context-sensitive rules are always dangerous. If you have a new keyword,
it should be valid in all contexts. That means that it mustn't be usable
for any other purpose.

>I do not understand why we should limit
>this to parameter declarations either. There is NO reason. It is always
>better to be able to pass more specific information to the compiler.

Where else would you use it ?

>Since identifiers starting with an underscore have been
>reserved for the compiler since quite a time,

This is not the case.

--
Clive D.W. Feather, writing for himself | Home: <cl...@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax) | Work: <cl...@demon.net>
Written on my laptop; please observe the Reply-To address

Clive D. W. Feather

unread,
Sep 24, 2001, 9:36:19 AM9/24/01
to
In article <9ol0ii$ea3$1...@wanadoo.fr>, jacob navia
<ja...@jacob.remcomp.fr> writes

>What I personally do not like in this is that the meaning of "static" has
>NOTHING to do with the semantics involved, i.e. it is surely NOT implying
>that the array is in the static storage area!
>
>Why misuse "static"?

Because we looked at a number of possibly syntaxes and decided that this
was the least painful. [For example, another proposal was to use [[ ]]
around the dimension.]

Clive D. W. Feather

unread,
Sep 24, 2001, 9:35:25 AM9/24/01
to
In article <9ol1i1$ofe$1...@wanadoo.fr>, jacob navia
<ja...@jacob.remcomp.fr> writes

>> To add to what Nick said, the purpose is to allow the use of data
>> pre-fetch instructions that some DSP and RISC and even some CISC
>> processors now have.

>The problem with those instructions is that


>1. They take code space, making the program larger.
>2. It is quite difficult to determine when and how to do that prefetching.

That's a quality-of-implementation issue.

>Leaving aside point 2, the speed delta between a P4 processor running at
>1500MHZ and RAM running about 20MHZ is now SO GREAT, that

[...]

Not all processors are P4s.

>> A compiler may completely ignore this keyword and take no action
>I think this is what I will do for lcc-win32. Anyway, if this kind of
>declaration appears outside a parameter scope I will put an error message,
>meaning that compilation will fail.

You must still make such tests in your compiler. All he meant was that,
once you've decided that the keyword is legal in a given context, you
can ignore it.

Nick Maclaren

unread,
Sep 24, 2001, 2:44:52 PM9/24/01
to
In article <slrn9quss2.19r.news_comp...@nightrunner.nmhq.net>,

Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
>On 24 Sep 2001 17:04:01 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
>>
>> |> I actually wonder why this new C99 feature is only available in function
>> |> prototypes. Wouldn't it be generally useful to be able to qualify a
>> |> pointer such that the implementation is allowed to rely on the first N
>> |> elements pointed to to be present?
>>
>> Yes, but consider the syntax :-(
>
>Pointer to array of static size. So what? :)

No, that is the semantics. How would you fit it into the existing
pointer declarator syntax?

jacob navia

unread,
Sep 24, 2001, 2:51:01 PM9/24/01
to
> >Why misuse "static"?
>
> Because we looked at a number of possibly syntaxes and decided that this
> was the least painful. [For example, another proposal was to use [[ ]]
> around the dimension.]

But why not solve the problem in a general way instead of using ad-hoc
solutions?

We need a firm statement from the ANSI comitee that all identifiers starting
with _ should be avoided because they are reserved for the standards
comitee. Period.

I mean you could use other sequences like __ but in any case, the standards
comitee should reserve a set of names to allow future keywords to be added
without much pain.

Niklas Matthies

unread,
Sep 24, 2001, 3:21:28 PM9/24/01
to
On 24 Sep 2001 18:44:52 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9quss2.19r.news_comp...@nightrunner.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
> >On 24 Sep 2001 17:04:01 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> >>
> >> |> I actually wonder why this new C99 feature is only available in function
> >> |> prototypes. Wouldn't it be generally useful to be able to qualify a
> >> |> pointer such that the implementation is allowed to rely on the first N
> >> |> elements pointed to to be present?
> >>
> >> Yes, but consider the syntax :-(
> >
> >Pointer to array of static size. So what? :)
>
> No, that is the semantics. How would you fit it into the existing
> pointer declarator syntax?

No, I meant syntax. If the syntax now allowed in prototypes would be
allowed in any declaration where an array type occurs, it could be
enabled to be used as follows:

int (p*)[static 42]; // p is pointer to array of >= 42 ints
p = ...;

...

int i = 42;
while (--i) // might prefetch *p here
{
...
if (some_condition())
{
do_something_with( (*p)[i] );
}
...
}

Yes, this syntactically requires an extra indirection (but only
syntactically), and is not quite compatible with the curent semantics
within prototypes. But it is a way to apply the current syntax to
generalized use.

With this,

int a[static 42];

would also be possible, but meaningless. (Because the actual number of
elements in a declared array object is known anyway).

The static size can be thought of as a qualifier for array types,
similar to const or volatile; it is just parameterized with an integer
constant.
This would/could also imply that pointers to static-sized arrays cannot
be converted to pointers to non-static-sized arrays or to static-sized
arrays with a greater size without a cast.

-- Niklas Matthies
--
War doesn't prove who's right, just who's left.

Marcin 'Qrczak' Kowalczyk

unread,
Sep 24, 2001, 6:05:39 PM9/24/01
to
Mon, 24 Sep 2001 14:36:19 +0100, Clive D. W. Feather <cl...@on-the-train.demon.co.uk> pisze:

> Because we looked at a number of possibly syntaxes and decided that this
> was the least painful. [For example, another proposal was to use [[ ]]
> around the dimension.]

IMHO 'void f(int a[>= 5])' would look better.

jacob navia

unread,
Sep 24, 2001, 7:54:12 PM9/24/01
to
<QUOTE>
int a[static 42];

would also be possible, but meaningless. (Because the actual number of
elements in a declared array object is known anyway).

</QUOTE>

what about
extern array[static 32];

Meaning that the external array has at least 32 elements?
I find this is the same as in function protos, sorry. This should be allowed
too, if we follow the logic behind it.

But excuse, I still do not get because if I (today, without C99) write:

int foo(int array[21]);

I AM specifying that the array at least has 21 elements. Since there is no
bounds checking in normal C, I do not see the need for the static specifier.
You can put any natural number there. I compiled this:
int foo(int array[42])
{
return array[43];
}

This compiled with NO warning in MSVC and gcc... even with the maximum
warning level ON.

So, C allows accessing an array beyond the specified length anyway. Why add
"static" then ?

jacob navia

unread,
Sep 25, 2001, 3:32:37 AM9/25/01
to
> Where else would you use it ?
>

extern int array[static 67];

for instance.


Nick Maclaren

unread,
Sep 25, 2001, 4:47:55 AM9/25/01
to
In article <slrn9qv1tn.1f0.news_comp...@nightrunner.nmhq.net>,

Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
>> >>
>> >> |> I actually wonder why this new C99 feature is only available in function
>> >> |> prototypes. Wouldn't it be generally useful to be able to qualify a
>> >> |> pointer such that the implementation is allowed to rely on the first N
>> >> |> elements pointed to to be present?
>> >>
>> >> Yes, but consider the syntax :-(
>> >
>> >Pointer to array of static size. So what? :)
>>
>> No, that is the semantics. How would you fit it into the existing
>> pointer declarator syntax?
>
>No, I meant syntax. If the syntax now allowed in prototypes would be
>allowed in any declaration where an array type occurs, it could be
>enabled to be used as follows:
>
> int (p*)[static 42]; // p is pointer to array of >= 42 ints

Ah. I see. That's not what you actually SAID, because that isn't
qualifying the pointer, but the array type it refers to. Yes, I
agree that idea has some potential, and cannot offhand think of any
major problems.

>Yes, this syntactically requires an extra indirection (but only
>syntactically), and is not quite compatible with the curent semantics
>within prototypes. But it is a way to apply the current syntax to
>generalized use.

Agreed. It was the qualification of pointer types as such that
made my mind boggle.

Niklas Matthies

unread,
Sep 25, 2001, 5:46:42 AM9/25/01
to
On 25 Sep 2001 08:47:55 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9qv1tn.1f0.news_comp...@nightrunner.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
> >> >>
> >> >> |> I actually wonder why this new C99 feature is only available in function
> >> >> |> prototypes. Wouldn't it be generally useful to be able to qualify a
> >> >> |> pointer such that the implementation is allowed to rely on the first N
> >> >> |> elements pointed to to be present?
> >> >>
> >> >> Yes, but consider the syntax :-(
> >> >
> >> >Pointer to array of static size. So what? :)
> >>
> >> No, that is the semantics. How would you fit it into the existing
> >> pointer declarator syntax?
> >
> >No, I meant syntax. If the syntax now allowed in prototypes would be
> >allowed in any declaration where an array type occurs, it could be
> >enabled to be used as follows:
> >
> > int (p*)[static 42]; // p is pointer to array of >= 42 ints
>
> Ah. I see. That's not what you actually SAID, because that isn't
> qualifying the pointer, but the array type it refers to.

Right, I was being inaccurate.

-- Niklas Matthies
--
No one can make you feel inferior without your consent.

Niklas Matthies

unread,
Sep 25, 2001, 6:13:19 AM9/25/01
to
On Tue, 25 Sep 2001 01:54:12 +0200, jacob navia <ja...@jacob.remcomp.fr> wrote:
> <QUOTE>
> int a[static 42];
>
> would also be possible, but meaningless. (Because the actual number of
> elements in a declared array object is known anyway).
> </QUOTE>
>
> what about
> extern array[static 32];
>
> Meaning that the external array has at least 32 elements?

While this would make some sense, the wording needed in the standard to
support this would be quite non-trivial.

> But excuse, I still do not get because if I (today, without C99) write:
>
> int foo(int array[21]);
>
> I AM specifying that the array at least has 21 elements.

No, you are declaring a pointer to int. See 6.7.5.3p7.

-- Niklas Matthies
--
Future is female: Unreliable, full of spoken promises,
pretty to look at, and horrible to face.

jacob navia

unread,
Sep 25, 2001, 7:56:04 AM9/25/01
to
> > But excuse, I still do not get it because if I (today, without C99)

write:
> >
> > int foo(int array[21]);
> >
> > I AM specifying that the array at least has 21 elements.
>
> No, you are declaring a pointer to int. See 6.7.5.3p7.
>

I quote from the standard

A declaration of a parameter as ''array of type'' shall be adjusted to
''qualified pointer to

type'', where the type qualifiers (if any) are those specified within the
[ and ] of the

array type derivation.


Translating this leaglese is quite difficult but I understand it as meaning:
1) I am declaring a qualified type pointer (int * in the example)
2) The qualifiers are the expression between the brackets
3) In the case of int array[21] the qualifier is the integer expression 21.

This means that the pointer points to an area of at least 21 elements!


James Russell Kuyper Jr.

unread,
Sep 25, 2001, 8:29:03 AM9/25/01
to

21 is in the right location to be a type qualifier, but it doesn't have
the right form to be one. The only legal type qualifiers are 'const' and
'volatile', and 'restrict' (6.7.1p3). If any one of those appeared in
that location, they would apply to the variable. However, 21 is simply
the leading array dimension, which gets adjusted out of existence, as
described in the section you quoted.



> This means that the pointer points to an area of at least 21 elements!

Incorrect. You need the 'static' keyword to get that effect.

Christian Bau

unread,
Sep 25, 2001, 8:35:18 AM9/25/01
to

The "21" is not a type qualifier. Type qualifiers would be things like
const or volatile.

int f (int array [const]) { ... } -> array is a const pointer to int.

But if you write
int f (int (*array) [21]) { ... } -> array is a pointer to an array of
21 ints.

Calling this is interesting. If you have arrays

int a [21];
int b [22];
int c [20];

then calling

f (a); f (b); f (c); /* illegal */
f (&a); /* legal */
f (&b); f (&c); /* illegal */

f ((int (*) [21]) &b); /* If I didn't type this wrong then it is
syntactically correct. */
f ((int (*) [21]) &c); /* Syntactically correct, but I am not sure if
using "array" in f is legal */

In the last case, array + 1 on its own would cause undefined behaviour;
I am not at all sure about anything else.

Clive D. W. Feather

unread,
Sep 26, 2001, 12:59:08 AM9/26/01
to
In article <9onval$8mu$1...@wanadoo.fr>, jacob navia
<ja...@jacob.remcomp.fr> writes

>> >Why misuse "static"?
>> Because we looked at a number of possibly syntaxes and decided that this
>> was the least painful. [For example, another proposal was to use [[ ]]
>> around the dimension.]
>But why not solve the problem in a general way instead of using ad-hoc
>solutions?

By "general way" you mean "a keyword from the reserved namespace" ? That
was indeed one of the options.

>We need a firm statement from the ANSI comitee that all identifiers starting
>with _ should be avoided because they are reserved for the standards
>comitee. Period.

No we don't.

>I mean you could use other sequences like __ but in any case, the standards
>comitee should reserve a set of names to allow future keywords to be added
>without much pain.

Have you *read* the Standard ? Even the 1990 one ?

Clive D. W. Feather

unread,
Sep 26, 2001, 1:02:55 AM9/26/01
to
In article <slrn9qvbhj...@qrnik.zagroda>, Marcin 'Qrczak'
Kowalczyk <qrc...@knm.org.pl> writes

>> Because we looked at a number of possibly syntaxes and decided that this
>> was the least painful. [For example, another proposal was to use [[ ]]
>> around the dimension.]
>
>IMHO 'void f(int a[>= 5])' would look better.

(1) That's very close to a valid expression (e.g. a[x >= 5]), which
makes errors more likely (compare = versus ==).

(2) The precedence of >= is wrong: e.g. a[>= 0x80 | 0x40]. Yes, a
compiler can handle this but human readers will have more trouble.

(3) a[>= const 5] doesn't look exactly great or obvious.

[Yes, none of these are insuperable. All the proposals, including a new
keyword, had downsides.]

Brian Inglis

unread,
Sep 30, 2001, 11:14:03 AM9/30/01
to
On Sun, 23 Sep 2001 18:10:43 +0200, "jacob navia"
<ja...@jacob.remcomp.fr> wrote:

[snip]

OT: comp.arch? anyone

>Leaving aside point 2, the speed delta between a P4 processor running at

>1500MHZ and RAM running about 20MHZ is now SO GREAT, that if the reading of

RAM is at least 133MHz/7.5ns (maybe you meant 200MHz/5ns) in
those boxes, so not so great, and hopefully recent data will be
in at least L2 cache (maybe 1.5ns nowadays -- not sure what Intel
builds into P4s?)

>those extra bytes for the prefetch instruction happens to be at the
>beginning of a 32 byte cache entry, so that the whole cache line would have
>to be brought into the L1 cache this would result in a big time loss. A
>1.5GHZ P4 has to put A LOT of wait cycles what would be a much bigger loss
>than the positive effects those prefetch instruction would achieve anyway.

I would assume the prefetch instruction queues an asynchronous
request for the memory controller to stage the data into L1
cache, avoiding a pipeline stall when the data is later accessed
by an instruction. I would also hope the memory controller queue
size is greater than the speed difference between L1 and RAM
(not up to date on CPU details -- they're fast enough for most of
us for now -- Nick may disagree!)

Thanks. Take care, Brian Inglis Calgary, Alberta, Canada
--
Brian....@CSi.com (Brian dot Inglis at SystematicSw dot ab dot ca)
fake address use address above to reply
tos...@aol.com ab...@aol.com ab...@yahoo.com ab...@hotmail.com ab...@msn.com ab...@sprint.com ab...@earthlink.com ab...@cadvision.com ab...@ibsystems.com u...@ftc.gov
spam traps

Nick Maclaren

unread,
Sep 30, 2001, 12:00:19 PM9/30/01
to
In article <mkvbrtc1p8fiapt63...@4ax.com>,

Brian Inglis <Brian.do...@SystematicSw.ab.ca> wrote:
>
>>those extra bytes for the prefetch instruction happens to be at the
>>beginning of a 32 byte cache entry, so that the whole cache line would have
>>to be brought into the L1 cache this would result in a big time loss. A
>>1.5GHZ P4 has to put A LOT of wait cycles what would be a much bigger loss
>>than the positive effects those prefetch instruction would achieve anyway.
>
>I would assume the prefetch instruction queues an asynchronous
>request for the memory controller to stage the data into L1
>cache, avoiding a pipeline stall when the data is later accessed
>by an instruction. I would also hope the memory controller queue
>size is greater than the speed difference between L1 and RAM
>(not up to date on CPU details -- they're fast enough for most of
>us for now -- Nick may disagree!)

Yes. The point is that the compiler has the OPTION of doing that
and, on some systems, it may be a big-time winner. Most modern
designs have come round to the conclusion that you need a fairly
large queue size, for precisely the reason you give. And I agree
that CPUs are fast enough for MOST of us - working in HPC hasn't
blinded me to the fact that it is a very specialised field!

Clive D. W. Feather

unread,
Oct 3, 2001, 8:54:56 AM10/3/01
to
In article <9opbun$rau$1...@wanadoo.fr>, jacob navia
<ja...@jacob.remcomp.fr> writes

>> Where else would you use it ?
>
>extern int array[static 67];
>
>for instance.

Which would have what useful meaning ? When would prefetch happen, if
ever ? What other use does it have ?

Niklas Matthies

unread,
Oct 3, 2001, 3:30:47 PM10/3/01
to
On Wed, 3 Oct 2001 13:54:56 +0100, Clive D. W. Feather <cl...@on-the-train.demon.co.uk> wrote:
> In article <9opbun$rau$1...@wanadoo.fr>, jacob navia
> <ja...@jacob.remcomp.fr> writes
> >> Where else would you use it ?
> >
> >extern int array[static 67];
> >
> >for instance.
>
> Which would have what useful meaning ? When would prefetch happen, if
> ever ? What other use does it have ?

I believe he means something like

int array[100];
...
extern int array[static 50]; // or some other integer <= 100

to be legal and refer to the same array of size 100.
Some other translation unit could include only the second declaration
and would (only) know that the array has at least 50 elements.

This would for example allow to increase the actual size of the array,
recompile the translation unit containing its definition, link it
with existing object modules compiled with the old header file
(containing the old, but static-declared size), and have the result
still be conforming to the standard in spite of differing sizes used
during compilation.

-- Niklas Matthies
--
Always remember: You're unique. Just like everyone else.

Nick Maclaren

unread,
Oct 3, 2001, 3:51:07 PM10/3/01
to
In article <5BVsT2ng...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>In article <9opbun$rau$1...@wanadoo.fr>, jacob navia
><ja...@jacob.remcomp.fr> writes
>>> Where else would you use it ?
>>
>>extern int array[static 67];
>>
>>for instance.
>
>Which would have what useful meaning ? When would prefetch happen, if
>ever ? What other use does it have ?

The answer to the second is "whenever the optimiser could make use
of the information". The answer to the others is less clear; in
this case, I can see no useful difference from the version without
the static.

Whether it has advantages in general depends very much on some
answers to questions of the form "what is an object, really?"
For example, let us say we have

extern double (* fred)[123];

and the program never refers to anything beyond (*fred)[7], is
it permitted for fred to be pointed at an array of less than 123
doubles?

If the answer is "yes", then extending the use of static could have
benefits. If the answer is "no", then there are the consistency
issues that I described in my document (and a lot more).

Clive D. W. Feather

unread,
Oct 11, 2001, 5:15:25 AM10/11/01
to
In article
<slrn9rmpr1.6r0.news_comp...@moongate.nmhq.net>,
Niklas Matthies <news_comp.std.c_e...@nmhq.net> writes

>I believe he means something like
>
> int array[100];
> ...
> extern int array[static 50]; // or some other integer <= 100

>This would for example allow to increase the actual size of the array,


>recompile the translation unit containing its definition, link it
>with existing object modules compiled with the old header file
>(containing the old, but static-declared size), and have the result
>still be conforming to the standard in spite of differing sizes used
>during compilation.

Hmm, yes, I see. It's a different usage but a useful one. Having said
that:
- if you're going to allow different sizes, why not just allow them
without needing another keyword;
- I don't know if all linkers allow this.

Niklas Matthies

unread,
Oct 11, 2001, 9:16:25 AM10/11/01
to
On Thu, 11 Oct 2001 10:15:25 +0100, Clive D. W. Feather <cl...@on-the-train.demon.co.uk> wrote:
> In article
> <slrn9rmpr1.6r0.news_comp...@moongate.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> writes
> >I believe he means something like
> >
> > int array[100];
> > ...
> > extern int array[static 50]; // or some other integer <= 100
>
> >This would for example allow to increase the actual size of the array,
> >recompile the translation unit containing its definition, link it
> >with existing object modules compiled with the old header file
> >(containing the old, but static-declared size), and have the result
> >still be conforming to the standard in spite of differing sizes used
> >during compilation.
>
> Hmm, yes, I see. It's a different usage but a useful one. Having said
> that:
> - if you're going to allow different sizes, why not just allow them
> without needing another keyword;

So that the implementation can distinguish between when it was intended
and when it wasn't, and can issue appropriate diagnostics.

> - I don't know if all linkers allow this.

Isn't this just a matter of the array's linkage name?

-- Niklas Matthies
--
If two people agree with each other all the time, then one of those
people is unnecessary.

Nick Maclaren

unread,
Oct 11, 2001, 10:46:23 AM10/11/01
to
In article <slrn9sb6t9.pd.news_comp....@nightrunner.nmhq.net>,

Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
>On Thu, 11 Oct 2001 10:15:25 +0100, Clive D. W. Feather <cl...@on-the-train.demon.co.uk> wrote:
>> In article
>> <slrn9rmpr1.6r0.news_comp...@moongate.nmhq.net>,
>> Niklas Matthies <news_comp.std.c_e...@nmhq.net> writes
>> >I believe he means something like
>> >
>> > int array[100];
>> > ...
>> > extern int array[static 50]; // or some other integer <= 100
>>
>> >This would for example allow to increase the actual size of the array,
>> >recompile the translation unit containing its definition, link it
>> >with existing object modules compiled with the old header file
>> >(containing the old, but static-declared size), and have the result
>> >still be conforming to the standard in spite of differing sizes used
>> >during compilation.
>>
>> Hmm, yes, I see. It's a different usage but a useful one. Having said
>> that:
>> - if you're going to allow different sizes, why not just allow them
>> without needing another keyword;
>
>So that the implementation can distinguish between when it was intended
>and when it wasn't, and can issue appropriate diagnostics.

Boggle. A new use of the word static! But I take your point.

>> - I don't know if all linkers allow this.
>
>Isn't this just a matter of the array's linkage name?

No. This is a nightmare area, though all the serious linkers that
I have looked at have had the ability to take the maximum size for
uninitialised arrays. Not all have for initialised ones.

This is because the old Fortran IV (and, yes, I mean IV and not 66)
semantics allowed COMMON blocks to be different sizes. That was
possible only for blank common in Fortran 66, if I recall.

Niklas Matthies

unread,
Oct 11, 2001, 12:33:59 PM10/11/01
to
On 11 Oct 2001 14:46:23 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9sb6t9.pd.news_comp....@nightrunner.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
> >On Thu, 11 Oct 2001 10:15:25 +0100, Clive D. W. Feather <cl...@on-the-train.demon.co.uk> wrote:
> >> In article
> >> <slrn9rmpr1.6r0.news_comp...@moongate.nmhq.net>,
> >> Niklas Matthies <news_comp.std.c_e...@nmhq.net> writes
> >> >I believe he means something like
> >> >
> >> > int array[100];
> >> > ...
> >> > extern int array[static 50]; // or some other integer <= 100
> >>
> >> >This would for example allow to increase the actual size of the array,
> >> >recompile the translation unit containing its definition, link it
> >> >with existing object modules compiled with the old header file
> >> >(containing the old, but static-declared size), and have the result
> >> >still be conforming to the standard in spite of differing sizes used
> >> >during compilation.
> >>
> >> Hmm, yes, I see. It's a different usage but a useful one. Having said
> >> that:
[毽愍

> >> - I don't know if all linkers allow this.
> >
> >Isn't this just a matter of the array's linkage name?
>
> No. This is a nightmare area, though all the serious linkers that
> I have looked at have had the ability to take the maximum size for
> uninitialised arrays. Not all have for initialised ones.

I never looked at linker technology in detail, but isn't it so that the
size is only needed in the module that contains the definition of that
data segment (i.e. the module that corresponds to the translation unit
that reserves storage space for the array), and other modules just
reference the array by its symbol by name?

-- Niklas Matthies
--

Nick Maclaren

unread,
Oct 11, 2001, 1:39:17 PM10/11/01
to
In article <slrn9sbifj.3rf.news_comp...@moongate.nmhq.net>,

Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
>
>I never looked at linker technology in detail, but isn't it so that the
>size is only needed in the module that contains the definition of that
>data segment (i.e. the module that corresponds to the translation unit
>that reserves storage space for the array), and other modules just
>reference the array by its symbol by name?

No. There is typically a difference between:

extern int a[5] = {1,2,3,4,5};
extern int b[5];
extern int c[];
extern int *c;

Not all systems will distinguish all cases, but some will. In the
cases when there are multiple definitions with different implied
lengths, the length used can be the first, last or maximum - and
in some cases, even more bizarre combinations.

I haven't investigated in several years, but Unix linkers were
typically incompatible crocks, though considerably better than the
ones on PC operating systems. And undocumented, of course. MVS
at least had a specification of safe practice, though compilers
often stepped outside that.

Niklas Matthies

unread,
Oct 11, 2001, 4:23:28 PM10/11/01
to
On 11 Oct 2001 17:39:17 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9sbifj.3rf.news_comp...@moongate.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
> >
> >I never looked at linker technology in detail, but isn't it so that the
> >size is only needed in the module that contains the definition of that
> >data segment (i.e. the module that corresponds to the translation unit
> >that reserves storage space for the array), and other modules just
> >reference the array by its symbol by name?
>
> No. There is typically a difference between:
>
> extern int a[5] = {1,2,3,4,5};
> extern int b[5];
> extern int c[];
> extern int *c;
>
> Not all systems will distinguish all cases, but some will. In the
> cases when there are multiple definitions with different implied
> lengths, the length used can be the first, last or maximum - and
> in some cases, even more bizarre combinations.

Still, as long as a linker supports the equivalent of "extern T a[]"
(and I guess all linkers are required to do so already), it is
compatible with the suggested model. The model doesn't require to be
able to actually distinguish "a[static N]" from "a[M]" and compare their
sizes or anything like that. The only requirement is that the compiler
translates "compatible-sized" array declarations into linkage symbols
that the linker recognizes to refer to the same object. One way to do
this would be to simply treat any "extern T a[static N]" as "extern T
a[]" as far as linking is concerned.

-- Niklas Matthies
--
The future ain't what it used to be...

Niklas Matthies

unread,
Oct 11, 2001, 4:24:54 PM10/11/01
to
On 11 Oct 2001 17:39:17 GMT, Nick Maclaren <nm...@cus.cam.ac.uk> wrote:
> In article <slrn9sbifj.3rf.news_comp...@moongate.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
> >
> >I never looked at linker technology in detail, but isn't it so that the
> >size is only needed in the module that contains the definition of that
> >data segment (i.e. the module that corresponds to the translation unit
> >that reserves storage space for the array), and other modules just
> >reference the array by its symbol by name?
>
> No. There is typically a difference between:
>
> extern int a[5] = {1,2,3,4,5};
> extern int b[5];
> extern int c[];
> extern int *c;
>
> Not all systems will distinguish all cases, but some will. In the
> cases when there are multiple definitions with different implied
> lengths, the length used can be the first, last or maximum - and
> in some cases, even more bizarre combinations.

Still, as long as a linker supports the equivalent of "extern T a[]"


(and I guess all linkers are required to do so already), it is

compatible with the suggested model. The model doesn't require the
linker to be able to actually distinguish "a[static N]" from "a[M]" and

Nick Maclaren

unread,
Oct 11, 2001, 4:26:27 PM10/11/01
to
In article <slrn9sbvtt.4t5.news_comp...@moongate.nmhq.net>,

Niklas Matthies <news_comp.std.c_e...@nmhq.net> wrote:
>
>Still, as long as a linker supports the equivalent of "extern T a[]"
>(and I guess all linkers are required to do so already), it is
>compatible with the suggested model. The model doesn't require to be
>able to actually distinguish "a[static N]" from "a[M]" and compare their
>sizes or anything like that. The only requirement is that the compiler
>translates "compatible-sized" array declarations into linkage symbols
>that the linker recognizes to refer to the same object. One way to do
>this would be to simply treat any "extern T a[static N]" as "extern T
>a[]" as far as linking is concerned.

Agreed. What is NOT possible is to support a reference increasing
the size of the definition, as some linkers can't do that. But you
weren't proposing that.

Wojtek Lerch

unread,
Oct 11, 2001, 4:50:27 PM10/11/01
to
"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message news:<u8p5cxIt...@romana.davros.org>...

> In article
> <slrn9rmpr1.6r0.news_comp...@moongate.nmhq.net>,
> Niklas Matthies <news_comp.std.c_e...@nmhq.net> writes
> >I believe he means something like
> >
> > int array[100];
> > ...
> > extern int array[static 50]; // or some other integer <= 100
>
> >This would for example allow to increase the actual size of the array,
> >recompile the translation unit containing its definition, link it
> >with existing object modules compiled with the old header file
> >(containing the old, but static-declared size), and have the result
> >still be conforming to the standard in spite of differing sizes used
> >during compilation.
>
> Hmm, yes, I see. It's a different usage but a useful one. Having said
> that:
> - if you're going to allow different sizes, why not just allow them
> without needing another keyword;

Because the proposed semantics are much more similar to

extern int array[];

than to

extern int array[ 50 ];

In particular, "int[static 50]" is an incomplete type. The compiler
is allowed to behave as if the square brackets were empty, with two
exceptions:

1 The types of "int arr[static 50]" and "int arr[30]" are incompatible
-- this way, having them in the same translation unit requires a
diagnostic.

2 If an array of unknown size is initialized, the size is calculated
from the initializer *and* any previously encountered declarations:

int arr[static 30];
int arr[] = { 1, 2 }; // arr has 30 elements, not two

> - I don't know if all linkers allow this.

I guess my interpretation differs from yours -- I don't see why this
would require the linker to be capable of doing anything that C
doesn't require already.

0 new messages