Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #68648 > unrolled thread

who invented static?

Started byfir <profesor.fir@gmail.com>
First post2015-08-29 11:40 -0700
Last post2015-09-05 01:24 +0000
Articles 20 on this page of 83 — 20 participants

Back to article view | Back to comp.lang.c


Contents

  who invented static? fir <profesor.fir@gmail.com> - 2015-08-29 11:40 -0700
    Re: who invented static? David Kleinecke <dkleinecke@gmail.com> - 2015-08-29 13:36 -0700
      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-08-29 13:46 -0700
        Re: who invented static? David Kleinecke <dkleinecke@gmail.com> - 2015-08-29 13:53 -0700
          Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-08-29 17:08 -0400
            Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-08-30 16:56 +0200
              Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-08-30 12:18 -0400
                Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-08-30 19:00 +0200
                  Re: who invented static? Richard Damon <Richard@Damon-Family.org> - 2015-08-30 13:23 -0400
                    Re: who invented static? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-08-30 21:18 +0100
                      Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-06 19:33 -0700
                    Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-06 19:26 -0700
                  Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-08-30 13:40 -0400
                    Re: who invented static? supercat@casperkitty.com - 2015-08-31 06:47 -0700
                    Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-06 19:20 -0700
                  Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-06 18:59 -0700
                    Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-07 10:25 +0200
                      Re: who invented static? Keith Thompson <kst-u@mib.org> - 2015-09-07 01:59 -0700
                        Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-07 12:22 +0200
                          Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-09-07 13:04 -0400
                            Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-07 21:25 +0200
                              Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-09-07 15:47 -0400
                                Re: who invented static? Philip Lantz <prl@canterey.us> - 2015-09-07 13:27 -0700
                                  Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-09-07 17:31 -0400
                                    Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-08 09:16 +0200
                              Re: who invented static? Keith Thompson <kst-u@mib.org> - 2015-09-07 13:27 -0700
                                Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-08 09:12 +0200
                              Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-07 16:06 -0700
                                Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-08 09:08 +0200
                                  Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-12 11:29 -0700
                                Re: who invented static? Keith Thompson <kst-u@mib.org> - 2015-09-08 10:18 -0700
                                  Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-09-08 13:28 -0400
                                  Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-11 10:07 -0700
                      Re: who invented static? Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-12 12:30 -0700
                        Re: who invented static? David Brown <david.brown@hesbynett.no> - 2015-09-13 15:48 +0200
                          Re: who invented static? supercat@casperkitty.com - 2015-09-29 09:04 -0700
                            Re: who invented static? Keith Thompson <kst-u@mib.org> - 2015-09-29 09:18 -0700
                              Re: who invented static? supercat@casperkitty.com - 2015-09-29 09:57 -0700
          Re: who invented static? fir <profesor.fir@gmail.com> - 2015-08-29 14:18 -0700
            Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-01 01:36 -0700
      Re: who invented static? Keith Thompson <kst-u@mib.org> - 2015-08-29 14:27 -0700
    Re: who invented static? Siri Cruz <chine.bleu@yahoo.com> - 2015-08-29 14:32 -0700
      Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-08-29 23:03 +0000
      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-01 01:52 -0700
        Re: who invented static? Robert Wessel <robertwessel2@yahoo.com> - 2015-09-01 23:42 -0500
          Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-02 00:14 -0700
            Re: who invented static? Richard Heathfield <rjh@cpax.org.uk> - 2015-09-02 08:24 +0100
          Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-04 04:25 +0000
            Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-04 00:45 -0700
              Re: who invented static? Robert Wessel <robertwessel2@yahoo.com> - 2015-09-04 04:09 -0500
                Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-04 02:35 -0700
                  Re: who invented static? Robert Wessel <robertwessel2@yahoo.com> - 2015-09-04 23:58 -0500
                    Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-05 03:02 -0700
                    Re: who invented static? wssimms@gmail.com - 2015-09-05 13:14 -0700
                      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-05 13:49 -0700
                      Re: who invented static? Siri Cruz <chine.bleu@yahoo.com> - 2015-09-05 14:09 -0700
                        Re: who invented static? gazelle@shell.xmission.com (Kenny McCormack) - 2015-09-05 22:30 +0000
                          Re: who invented static? wssimms@gmail.com - 2015-09-05 20:41 -0700
                            Re: who invented static? gazelle@shell.xmission.com (Kenny McCormack) - 2015-09-06 05:28 +0000
                              Re: who invented static? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-09-05 22:40 -0700
                            Re: who invented static? James Kuyper <jameskuyper@verizon.net> - 2015-09-06 11:42 -0400
                      Re: who invented static? Robert Wessel <robertwessel2@yahoo.com> - 2015-09-05 23:38 -0500
                      Re: who invented static? raltbos@xs4all.nl (Richard Bos) - 2015-09-27 21:25 +0000
                        Re: who invented static? Siri Cruz <chine.bleu@yahoo.com> - 2015-09-27 14:53 -0700
                          Re: who invented static? Thomas Richter <thor@math.tu-berlin.de> - 2015-09-29 01:46 +0200
                          Re: who invented static? raltbos@xs4all.nl (Richard Bos) - 2015-10-02 12:52 +0000
              Re: who invented static? Siri Cruz <chine.bleu@yahoo.com> - 2015-09-04 02:34 -0700
                Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-04 02:43 -0700
                Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-05 01:30 +0000
                  Re: who invented static? Siri Cruz <chine.bleu@yahoo.com> - 2015-09-04 20:52 -0700
                    Re: who invented static? Robert Wessel <robertwessel2@yahoo.com> - 2015-09-05 00:03 -0500
                    Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-05 09:04 +0000
                      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-05 03:02 -0700
                      Re: who invented static? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-09-05 04:33 -0700
                        Re: who invented static? Reinhardt Behm <rbehm@hushmail.com> - 2015-09-05 20:08 +0800
                          Re: who invented static? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-09-05 05:21 -0700
                            Re: who invented static? "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-09-05 06:37 -0700
                          Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-05 16:54 +0000
                    Re: who invented static? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-05 11:06 +0100
                      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-05 03:17 -0700
                    Re: who invented static? raltbos@xs4all.nl (Richard Bos) - 2015-09-05 19:14 +0000
                      Re: who invented static? fir <profesor.fir@gmail.com> - 2015-09-05 12:59 -0700
              Re: who invented static? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-05 01:24 +0000

Page 1 of 5  [1] 2 3 4 5  Next page →


#68648 — who invented static?

Fromfir <profesor.fir@gmail.com>
Date2015-08-29 11:40 -0700
Subjectwho invented static?
Message-ID<661ee2d4-d23e-4602-a48b-86c669001de6@googlegroups.com>
i know it may be hard to answer but as
i vaguelly know (maybe wrong), static sields (i mean like static ints or arrays in functions) are absent in previous version of the language I mean b  by thompson (69/70) and c by ritchie (72/73)..it was added later* - if so WHO invented it? has it some derivative from previous language or something?

* which year it was added?

[toc] | [next] | [standalone]


#68654

FromDavid Kleinecke <dkleinecke@gmail.com>
Date2015-08-29 13:36 -0700
Message-ID<4e9adb87-3258-4b90-92b5-f9e89674f504@googlegroups.com>
In reply to#68648
On Saturday, August 29, 2015 at 11:41:03 AM UTC-7, fir wrote:
> i know it may be hard to answer but as
> i vaguelly know (maybe wrong), static sields (i mean like static ints or arrays in functions) are absent in previous version of the language I mean b  by thompson (69/70) and c by ritchie (72/73)..it was added later* - if so WHO invented it? has it some derivative from previous language or something?
> 
> * which year it was added?

There are four entries in the index of my copy of K&R 1974 for "static"
this or that.

[toc] | [prev] | [next] | [standalone]


#68655

Fromfir <profesor.fir@gmail.com>
Date2015-08-29 13:46 -0700
Message-ID<23d45408-26bc-46a3-8b48-2593b5c29ad4@googlegroups.com>
In reply to#68654
W dniu sobota, 29 sierpnia 2015 22:37:02 UTC+2 użytkownik David Kleinecke napisał:
> On Saturday, August 29, 2015 at 11:41:03 AM UTC-7, fir wrote:
> > i know it may be hard to answer but as
> > i vaguelly know (maybe wrong), static sields (i mean like static ints or arrays in functions) are absent in previous version of the language I mean b  by thompson (69/70) and c by ritchie (72/73)..it was added later* - if so WHO invented it? has it some derivative from previous language or something?
> > 
> > * which year it was added?
> 
> There are four entries in the index of my copy of K&R 1974 for "static"
> this or that.

but for what static - old static means that function is internal to module/(compilation unit)

im not sure but probably the other static was not yet ready present in 74

[toc] | [prev] | [next] | [standalone]


#68656

FromDavid Kleinecke <dkleinecke@gmail.com>
Date2015-08-29 13:53 -0700
Message-ID<6036cc6f-2804-45c2-95f4-e19a5fa9399d@googlegroups.com>
In reply to#68655
On Saturday, August 29, 2015 at 1:46:40 PM UTC-7, fir wrote:
> W dniu sobota, 29 sierpnia 2015 22:37:02 UTC+2 użytkownik David Kleinecke napisał:
> > On Saturday, August 29, 2015 at 11:41:03 AM UTC-7, fir wrote:
> > > i know it may be hard to answer but as
> > > i vaguelly know (maybe wrong), static sields (i mean like static ints or arrays in functions) are absent in previous version of the language I mean b  by thompson (69/70) and c by ritchie (72/73)..it was added later* - if so WHO invented it? has it some derivative from previous language or something?
> > > 
> > > * which year it was added?
> > 
> > There are four entries in the index of my copy of K&R 1974 for "static"
> > this or that.
> 
> but for what static - old static means that function is internal to module/(compilation unit)
> 
> im not sure but probably the other static was not yet ready present in 74

static declaration 89
static storeage class 28, 80, 191
static variables, external 80
static variables, internal 80

[toc] | [prev] | [next] | [standalone]


#68659

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-08-29 17:08 -0400
Message-ID<55E21F50.2080705@verizon.net>
In reply to#68656
On 08/29/2015 04:53 PM, David Kleinecke wrote:
> On Saturday, August 29, 2015 at 1:46:40 PM UTC-7, fir wrote:
>> W dniu sobota, 29 sierpnia 2015 22:37:02 UTC+2 użytkownik David Kleinecke napisał:
...
>>> There are four entries in the index of my copy of K&R 1974 for "static"
>>> this or that.
>>
>> but for what static - old static means that function is internal to module/(compilation unit)
>>
>> im not sure but probably the other static was not yet ready present in 74
> 
> static declaration 89
> static storeage class 28, 80, 191
> static variables, external 80
> static variables, internal 80

I own a copy of the first edition of K&R, but I lost track of it the
last time I moved, so I can't confirm those. In the current standard,
'static' has three meanings:

"If the declaration of a file scope identifier for an object or a
function contains the storage class specifier static, the identifier has
internal linkage." (6.2.2p3)

I'd expect that to correspond to the description on pages 28 and 191.

"An object whose identifier is declared ... with the storage-class
specifier static, has static storage duration." 6.2.4p3

I'd expect that both of these meanings would be explained (and
distinguished?) on page 80.

Could you compare those  pages with the cited sections of the C standard?

The following use of "static" is new in C99, and can only occur in the
leading dimension of a function parameter declared as an array:
"If the keyword static also appears within the [ and ] of the array type
derivation, then for each call to the function, the value of the
corresponding actual argument shall provide access to the first element
of an array with at least as many elements as specified by the size
expression." 6.7.6.3p7

This obviously should have no counterpart in K&R C.

[toc] | [prev] | [next] | [standalone]


#68688

FromDavid Brown <david.brown@hesbynett.no>
Date2015-08-30 16:56 +0200
Message-ID<mrv5f3$g9b$1@dont-email.me>
In reply to#68659
On 29/08/15 23:08, James Kuyper wrote:

> The following use of "static" is new in C99, and can only occur in the
> leading dimension of a function parameter declared as an array:
> "If the keyword static also appears within the [ and ] of the array type
> derivation, then for each call to the function, the value of the
> corresponding actual argument shall provide access to the first element
> of an array with at least as many elements as specified by the size
> expression." 6.7.6.3p7
>
> This obviously should have no counterpart in K&R C.
>

This last use of "static" is completely new to me.  I can see the 
corresponding paragraph in the C11 standards (since that's the one I 
have handy), but I can't figure out what it means or what it is for. 
All I can see is this:

EXAMPLE 5
The following are all compatible function prototype declarators.

	double maximum(int n, int m, double a[n][m]);
	double maximum(int n, int m, double a[*][*]);
	double maximum(int n, int m, double a[ ][*]);
	double maximum(int n, int m, double a[ ][m]);

as are:

	void f(double (* restrict a)[5]);
	void f(double a[restrict][5]);
	void f(double a[restrict 3][5]);
	void f(double a[restrict static 3][5]);

This is not something I have come across before, and I would be grateful 
for hints or pointers as to what it means and how it is used.

[toc] | [prev] | [next] | [standalone]


#68693

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-08-30 12:18 -0400
Message-ID<55E32CBB.2050001@verizon.net>
In reply to#68688
On 08/30/2015 10:56 AM, David Brown wrote:
> On 29/08/15 23:08, James Kuyper wrote:
> 
>> The following use of "static" is new in C99, and can only occur in the
>> leading dimension of a function parameter declared as an array:
>> "If the keyword static also appears within the [ and ] of the array type
>> derivation, then for each call to the function, the value of the
>> corresponding actual argument shall provide access to the first element
>> of an array with at least as many elements as specified by the size
>> expression." 6.7.6.3p7
>>
>> This obviously should have no counterpart in K&R C.
>>
> 
> This last use of "static" is completely new to me.  I can see the 
> corresponding paragraph in the C11 standards (since that's the one I 
> have handy), but I can't figure out what it means or what it is for. 


Given:

    void f(int array[static 3]);
    int large_array[6];
    int small_array[2];
    int *p = small_array;

then f(large_array) is fine, because large_array has more than 3
elements. However, f(small_array) violates a "shall" that occurs outside
of a constraint, because small_array has fewer than 3 elements. The
behavior is therefore undefined. I would have preferred that this be a
constraint violation, and I would expect any decent implementation of
C99 or later to issue the diagnostic message that would be mandatory if
it were a constraint violation - in my opinion, that possibility is the
only thing that makes this feature worthwhile. I think that the reason
why it cannot be made a constraint violation is that f(p) is also a
violation of the same rule, and unlike f(small_array), it's not in
general easy for a compiler to identify the fact that an arbitrary
pointer points at location which violates this rule.

[toc] | [prev] | [next] | [standalone]


#68699

FromDavid Brown <david.brown@hesbynett.no>
Date2015-08-30 19:00 +0200
Message-ID<mrvcnh$fju$1@dont-email.me>
In reply to#68693
On 30/08/15 18:18, James Kuyper wrote:
> On 08/30/2015 10:56 AM, David Brown wrote:
>> On 29/08/15 23:08, James Kuyper wrote:
>>
>>> The following use of "static" is new in C99, and can only occur in the
>>> leading dimension of a function parameter declared as an array:
>>> "If the keyword static also appears within the [ and ] of the array type
>>> derivation, then for each call to the function, the value of the
>>> corresponding actual argument shall provide access to the first element
>>> of an array with at least as many elements as specified by the size
>>> expression." 6.7.6.3p7
>>>
>>> This obviously should have no counterpart in K&R C.
>>>
>>
>> This last use of "static" is completely new to me.  I can see the
>> corresponding paragraph in the C11 standards (since that's the one I
>> have handy), but I can't figure out what it means or what it is for.
>
>
> Given:
>
>      void f(int array[static 3]);
>      int large_array[6];
>      int small_array[2];
>      int *p = small_array;
>
> then f(large_array) is fine, because large_array has more than 3
> elements. However, f(small_array) violates a "shall" that occurs outside
> of a constraint, because small_array has fewer than 3 elements. The
> behavior is therefore undefined. I would have preferred that this be a
> constraint violation, and I would expect any decent implementation of
> C99 or later to issue the diagnostic message that would be mandatory if
> it were a constraint violation - in my opinion, that possibility is the
> only thing that makes this feature worthwhile. I think that the reason
> why it cannot be made a constraint violation is that f(p) is also a
> violation of the same rule, and unlike f(small_array), it's not in
> general easy for a compiler to identify the fact that an arbitrary
> pointer points at location which violates this rule.
>

But surely if g were defined:

	void g(int array[3]);

Then g(small_array) would still be a constraint violation?  Or is it 
defined behaviour to call g(small_array), and only becomes undefined if 
g() accesses array[2] ?

It seems to me that even without the "static", g is asking for a 
parameter with particular characteristics, and calling g(small_array) is 
breaking that requirement.

It also seems to me to be a /really/ odd choice to make this another use 
of the "static" keyword.  If a keyword is needed here (I think the 
"static" behaviour is the only sensible one, and should be the case 
without the keyword), then I would go for a new keyword such as 
"__I_really_mean_it" :-)


Is this a use of "static" that you have seen in real code?  Is it used much?

Thanks,

David

[toc] | [prev] | [next] | [standalone]


#68701

FromRichard Damon <Richard@Damon-Family.org>
Date2015-08-30 13:23 -0400
Message-ID<m_GEx.8461$1H1.2009@fx23.iad>
In reply to#68699
On 8/30/15 1:00 PM, David Brown wrote:
> On 30/08/15 18:18, James Kuyper wrote:
>> On 08/30/2015 10:56 AM, David Brown wrote:
>>> On 29/08/15 23:08, James Kuyper wrote:
>>>
>>>> The following use of "static" is new in C99, and can only occur in the
>>>> leading dimension of a function parameter declared as an array:
>>>> "If the keyword static also appears within the [ and ] of the array
>>>> type
>>>> derivation, then for each call to the function, the value of the
>>>> corresponding actual argument shall provide access to the first element
>>>> of an array with at least as many elements as specified by the size
>>>> expression." 6.7.6.3p7
>>>>
>>>> This obviously should have no counterpart in K&R C.
>>>>
>>>
>>> This last use of "static" is completely new to me.  I can see the
>>> corresponding paragraph in the C11 standards (since that's the one I
>>> have handy), but I can't figure out what it means or what it is for.
>>
>>
>> Given:
>>
>>      void f(int array[static 3]);
>>      int large_array[6];
>>      int small_array[2];
>>      int *p = small_array;
>>
>> then f(large_array) is fine, because large_array has more than 3
>> elements. However, f(small_array) violates a "shall" that occurs outside
>> of a constraint, because small_array has fewer than 3 elements. The
>> behavior is therefore undefined. I would have preferred that this be a
>> constraint violation, and I would expect any decent implementation of
>> C99 or later to issue the diagnostic message that would be mandatory if
>> it were a constraint violation - in my opinion, that possibility is the
>> only thing that makes this feature worthwhile. I think that the reason
>> why it cannot be made a constraint violation is that f(p) is also a
>> violation of the same rule, and unlike f(small_array), it's not in
>> general easy for a compiler to identify the fact that an arbitrary
>> pointer points at location which violates this rule.
>>
>
> But surely if g were defined:
>
>      void g(int array[3]);
>
> Then g(small_array) would still be a constraint violation?  Or is it
> defined behaviour to call g(small_array), and only becomes undefined if
> g() accesses array[2] ?
>
> It seems to me that even without the "static", g is asking for a
> parameter with particular characteristics, and calling g(small_array) is
> breaking that requirement.
>

in c, this definition of g is IDENTICAL to (by a rewrite rule)
   void g(int *array);

(note, the 3 is lost)
Thus, the passing of anything that is an int* or decays to an int* (like 
an array of any size of int) is valid.

Adding the static keyword changes the type of that parameter so that the 
compiler actually remembers the needed bounds, and will check that the 
passed array is large enough.

> It also seems to me to be a /really/ odd choice to make this another use
> of the "static" keyword.  If a keyword is needed here (I think the
> "static" behaviour is the only sensible one, and should be the case
> without the keyword), then I would go for a new keyword such as
> "__I_really_mean_it" :-)
>

This is one of the cases where the Standards Committee decided that it 
was better to reuse an old keyword in a different context rather than 
needing to come up with a new "ugly" (to be backwards compatible) keyword.

Note, that the conversion of arrays to pointers in this context goes all 
the way back to K&R (and earlier) in the 70's and changing the behavior 
would break a number of programs, so it couldn't be made the default.

>
> Is this a use of "static" that you have seen in real code?  Is it used
> much?
>
> Thanks,
>
> David
>

[toc] | [prev] | [next] | [standalone]


#68721

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-08-30 21:18 +0100
Message-ID<87io7wwmwu.fsf@bsb.me.uk>
In reply to#68701
Richard Damon <Richard@Damon-Family.org> writes:

> On 8/30/15 1:00 PM, David Brown wrote:
>> On 30/08/15 18:18, James Kuyper wrote:
>>> On 08/30/2015 10:56 AM, David Brown wrote:
>>>> On 29/08/15 23:08, James Kuyper wrote:
>>>>
>>>>> The following use of "static" is new in C99, and can only occur in the
>>>>> leading dimension of a function parameter declared as an array:
>>>>> "If the keyword static also appears within the [ and ] of the array
>>>>> type
>>>>> derivation, then for each call to the function, the value of the
>>>>> corresponding actual argument shall provide access to the first element
>>>>> of an array with at least as many elements as specified by the size
>>>>> expression." 6.7.6.3p7
<snip>
>>> Given:
>>>
>>>      void f(int array[static 3]);
>>>      int large_array[6];
>>>      int small_array[2];
>>>      int *p = small_array;
>>>
>>> then f(large_array) is fine, because large_array has more than 3
>>> elements. However, f(small_array) violates a "shall" that occurs outside
>>> of a constraint, because small_array has fewer than 3 elements. The
>>> behavior is therefore undefined. I would have preferred that this be a
>>> constraint violation, and I would expect any decent implementation of
>>> C99 or later to issue the diagnostic message that would be mandatory if
>>> it were a constraint violation - in my opinion, that possibility is the
>>> only thing that makes this feature worthwhile. I think that the reason
>>> why it cannot be made a constraint violation is that f(p) is also a
>>> violation of the same rule, and unlike f(small_array), it's not in
>>> general easy for a compiler to identify the fact that an arbitrary
>>> pointer points at location which violates this rule.

I think it's simpler to say that it can't be a constraint because it
can't be diagnosed.  You could come up with some set of rules about what
deductions a compiler must use, and then base a rather complex
constraint on those but it would be a bit arbitrary.

>> But surely if g were defined:
>>
>>      void g(int array[3]);
>>
>> Then g(small_array) would still be a constraint violation?  Or is it
>> defined behaviour to call g(small_array), and only becomes undefined if
>> g() accesses array[2] ?
>>
>> It seems to me that even without the "static", g is asking for a
>> parameter with particular characteristics, and calling g(small_array) is
>> breaking that requirement.
>
> in c, this definition of g is IDENTICAL to (by a rewrite rule)
>   void g(int *array);
>
> (note, the 3 is lost)
> Thus, the passing of anything that is an int* or decays to an int*
> (like an array of any size of int) is valid.
>
> Adding the static keyword changes the type of that parameter so that
> the compiler actually remembers the needed bounds, and will check that
> the passed array is large enough.

The compiler can't always do that check but maybe you were talking about
the example given.  Anyway, where does the idea that static changes the
type of the parameter come from?  I don't see that at all.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#69728

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-06 19:33 -0700
Message-ID<kfn613nnelf.fsf@x-alumni2.alumni.caltech.edu>
In reply to#68721
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Richard Damon <Richard@Damon-Family.org> writes:
>
>> On 8/30/15 1:00 PM, David Brown wrote:
>>> On 30/08/15 18:18, James Kuyper wrote:
>>>> On 08/30/2015 10:56 AM, David Brown wrote:
>>>>> On 29/08/15 23:08, James Kuyper wrote:
>>>>>
>>>>>> The following use of "static" is new in C99, and can only occur in the
>>>>>> leading dimension of a function parameter declared as an array:
>>>>>> "If the keyword static also appears within the [ and ] of the array
>>>>>> type
>>>>>> derivation, then for each call to the function, the value of the
>>>>>> corresponding actual argument shall provide access to the first element
>>>>>> of an array with at least as many elements as specified by the size
>>>>>> expression."  6.7.6.3p7
>
> <snip>
>
>>>> Given:
>>>>
>>>>      void f(int array[static 3]);
>>>>      int large_array[6];
>>>>      int small_array[2];
>>>>      int *p = small_array;
>>>>
>>>> then f(large_array) is fine, because large_array has more than 3
>>>> elements.  However, f(small_array) violates a "shall" that occurs outside
>>>> of a constraint, because small_array has fewer than 3 elements.  The
>>>> behavior is therefore undefined.  I would have preferred that this be a
>>>> constraint violation, and I would expect any decent implementation of
>>>> C99 or later to issue the diagnostic message that would be mandatory if
>>>> it were a constraint violation - in my opinion, that possibility is the
>>>> only thing that makes this feature worthwhile.  I think that the reason
>>>> why it cannot be made a constraint violation is that f(p) is also a
>>>> violation of the same rule, and unlike f(small_array), it's not in
>>>> general easy for a compiler to identify the fact that an arbitrary
>>>> pointer points at location which violates this rule.
>
> I think it's simpler to say that it can't be a constraint because it
> can't be diagnosed.  [snip]

Not only that, but the use of 'static' could be given just
in the function definition, but not in any declarations.
The "shall" requirement still applies, but the information
simply isn't there in other translation units.

>>> But surely if g were defined:
>>>
>>>      void g(int array[3]);
>>>
>>> Then g(small_array) would still be a constraint violation?  Or is it
>>> defined behaviour to call g(small_array), and only becomes undefined if
>>> g() accesses array[2] ?
>>>
>>> It seems to me that even without the "static", g is asking for a
>>> parameter with particular characteristics, and calling g(small_array) is
>>> breaking that requirement.
>>
>> in c, this definition of g is IDENTICAL to (by a rewrite rule)
>>   void g(int *array);
>>
>> (note, the 3 is lost)
>> Thus, the passing of anything that is an int* or decays to an int*
>> (like an array of any size of int) is valid.
>>
>> Adding the static keyword changes the type of that parameter so that
>> the compiler actually remembers the needed bounds, and will check that
>> the passed array is large enough.
>
> The compiler can't always do that check but maybe you were talking about
> the example given.  Anyway, where does the idea that static changes the
> type of the parameter come from?  I don't see that at all.

Using 'static' in this way does not change the type of the
parameter.  How it behaves is analogous to type qualifiers,
eg, 'const' or 'restrict' - there is an effect on the
function definition, but no effect for calls.

[toc] | [prev] | [next] | [standalone]


#69727

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-06 19:26 -0700
Message-ID<kfna8szneww.fsf@x-alumni2.alumni.caltech.edu>
In reply to#68701
Richard Damon <Richard@Damon-Family.org> writes:

> On 8/30/15 1:00 PM, David Brown wrote:
>> On 30/08/15 18:18, James Kuyper wrote:
>>> On 08/30/2015 10:56 AM, David Brown wrote:
>>>> On 29/08/15 23:08, James Kuyper wrote:
>>>>
>>>>> The following use of "static" is new in C99, and can only occur in the
>>>>> leading dimension of a function parameter declared as an array:
>>>>> "If the keyword static also appears within the [ and ] of the array
>>>>> type
>>>>> derivation, then for each call to the function, the value of the
>>>>> corresponding actual argument shall provide access to the first element
>>>>> of an array with at least as many elements as specified by the size
>>>>> expression."  6.7.6.3p7
>>>>>
>>>>> This obviously should have no counterpart in K&R C.
>>>>
>>>> This last use of "static" is completely new to me.  I can see the
>>>> corresponding paragraph in the C11 standards (since that's the one I
>>>> have handy), but I can't figure out what it means or what it is for.
>>>
>>> Given:
>>>
>>>      void f(int array[static 3]);
>>>      int large_array[6];
>>>      int small_array[2];
>>>      int *p = small_array;
>>>
>>> then f(large_array) is fine, because large_array has more than 3
>>> elements.  However, f(small_array) violates a "shall" that occurs outside
>>> of a constraint, because small_array has fewer than 3 elements.  The
>>> behavior is therefore undefined.  I would have preferred that this be a
>>> constraint violation, and I would expect any decent implementation of
>>> C99 or later to issue the diagnostic message that would be mandatory if
>>> it were a constraint violation - in my opinion, that possibility is the
>>> only thing that makes this feature worthwhile.  I think that the reason
>>> why it cannot be made a constraint violation is that f(p) is also a
>>> violation of the same rule, and unlike f(small_array), it's not in
>>> general easy for a compiler to identify the fact that an arbitrary
>>> pointer points at location which violates this rule.
>>
>> But surely if g were defined:
>>
>>      void g(int array[3]);
>>
>> Then g(small_array) would still be a constraint violation?  Or is it
>> defined behaviour to call g(small_array), and only becomes undefined if
>> g() accesses array[2] ?
>>
>> It seems to me that even without the "static", g is asking for a
>> parameter with particular characteristics, and calling g(small_array) is
>> breaking that requirement.
>
> in c, this definition of g is IDENTICAL to (by a rewrite rule)
>   void g(int *array);
>
> (note, the 3 is lost)
> Thus, the passing of anything that is an int* or decays to an int*
> (like an array of any size of int) is valid.
>
> Adding the static keyword changes the type of that parameter

No, it doesn't.

> so that
> the compiler actually remembers the needed bounds, and will check that
> the passed array is large enough.

No such check is required.  Normally the only effect of 'static'
parameters will be where the function in question is defined, not
where it is called.

[toc] | [prev] | [next] | [standalone]


#68702

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-08-30 13:40 -0400
Message-ID<55E34023.5010809@verizon.net>
In reply to#68699
On 08/30/2015 01:00 PM, David Brown wrote:
> On 30/08/15 18:18, James Kuyper wrote:
...
>> Given:
>>
>>      void f(int array[static 3]);
>>      int large_array[6];
>>      int small_array[2];
>>      int *p = small_array;
>>
>> then f(large_array) is fine, because large_array has more than 3
>> elements. However, f(small_array) violates a "shall" that occurs outside
>> of a constraint, because small_array has fewer than 3 elements. The
>> behavior is therefore undefined. I would have preferred that this be a
>> constraint violation, and I would expect any decent implementation of
>> C99 or later to issue the diagnostic message that would be mandatory if
>> it were a constraint violation - in my opinion, that possibility is the
>> only thing that makes this feature worthwhile. I think that the reason
>> why it cannot be made a constraint violation is that f(p) is also a
>> violation of the same rule, and unlike f(small_array), it's not in
>> general easy for a compiler to identify the fact that an arbitrary
>> pointer points at location which violates this rule.
>>
> 
> But surely if g were defined:
> 
> 	void g(int array[3]);
> 
> Then g(small_array) would still be a constraint violation?

No. See the first part of 6.7.6.3p7: "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."

This means that the declaration is adjusted to
	void g(int *array);

It might not be obvious from the above wording, but for multidimensional
arrays, this only affects the leading dimension of the array.

> ...  Or is it 
> defined behaviour to call g(small_array), and only becomes undefined if 
> g() accesses array[2] ?

Correct.

> It seems to me that even without the "static", g is asking for a 
> parameter with particular characteristics, and calling g(small_array) is 
> breaking that requirement.

6.7.6.3p7 mandates removal of the information identifying that
characteristic. I won't argue that this was a wise choice. Were I
designing my own language without worrying about backwards compatibility
with C, arrays would not automatically convert to pointers, and array
parameter declarations would not be "adjusted" into pointer
declarations, and array dimensions (if specified, which they wouldn't
have to be) would be one of the things that would have to match in order
for two types to be compatible.

That approach has it's own complications: how to apply a function
expecting a 3x5 array, to the 3rd, 4th, and 5th rows of a 7x5 array? In
C that's trivial, but the language I'm describing would need some
un-C-like construct to achieve that result. IDL has array[*,2:4], but
what that does is create a new array containing only rows 2-4 of the
array - it doesn't refer to rows 2-4 of the existing array.

> It also seems to me to be a /really/ odd choice to make this another use 
> of the "static" keyword. ...

I agree.

> Is this a use of "static" that you have seen in real code?  Is it used much?

In the late 1990s, rules were set up from the project I'm working on
that specified that all of our code must be either C95, Fortran 77,
Fortran 90, or Ada. None of the project code uses Ada, but the other
three are all in use. Those rules have never, as far as I know, been
updated. Therefore, we can't use this feature. I would use it, if I
could, but only because I would hope for the diagnostic message that the
standard fails to mandate for violations. Strictly speaking, this clause
only serves to make the behavior of some code undefined.

[toc] | [prev] | [next] | [standalone]


#68752

Fromsupercat@casperkitty.com
Date2015-08-31 06:47 -0700
Message-ID<9352ca95-aca5-46f0-8960-9471b832d245@googlegroups.com>
In reply to#68702
On Sunday, August 30, 2015 at 12:41:04 PM UTC-5, James Kuyper wrote:
> That approach has it's own complications: how to apply a function
> expecting a 3x5 array, to the 3rd, 4th, and 5th rows of a 7x5 array? In
> C that's trivial, but the language I'm describing would need some
> un-C-like construct to achieve that result. IDL has array[*,2:4], but
> what that does is create a new array containing only rows 2-4 of the
> array - it doesn't refer to rows 2-4 of the existing array.

It's too bad C makes no syntactic distinction between a pointer to a "whole" object, versus checked or unchecked pointers to a chunk of an object, since such a distinction would have allowed improved efficiency and robustness on many architectures (on 8086, for example, aligning things whose addresses are taken to multiples of 16 bytes would have allowed code to use "segment-only" pointers, and use offsets directly off segments), and would also have allowed systems to have the "checked partial-object" pointers combine a base and offset, thus retaining the means to perform array-bounds checking [though compilers optimizing for speed could simply pass an address as they do now].

If base-only pointer types could use a bit at their destination to identify the kind of a pointer, then it would be possible to allow pointers to identify either a direct address or the address of a structure containing a base-object address, offset, and range information.  Allowing for such accesses would probably be too slow to be worthwhile in common compiler-generated code, but could have been useful for things like string library functions.  Say that each string pointer may either point to a length-prefixed string or string buffer (using a variable-length coding for the length or a data structure holding a pointer to character data, the length of the string, and the size of the buffer holding the string.  That would have allowed string-handling code to use
bounds-checked buffers with efficiency comparable to zero-terminated strings.

[toc] | [prev] | [next] | [standalone]


#69726

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-06 19:20 -0700
Message-ID<kfnegibnf65.fsf@x-alumni2.alumni.caltech.edu>
In reply to#68702
James Kuyper <jameskuyper@verizon.net> writes:

> On 08/30/2015 01:00 PM, David Brown wrote:
>> On 30/08/15 18:18, James Kuyper wrote:
>
> ...
>
>>> Given:
>>>
>>>      void f(int array[static 3]);
>>>      int large_array[6];
>>>      int small_array[2];
>>>      int *p = small_array;
>>>
>>> then f(large_array) is fine, because large_array has more than 3
>>> elements.  However, f(small_array) violates a "shall" that occurs outside
>>> of a constraint, because small_array has fewer than 3 elements.  The
>>> behavior is therefore undefined.  I would have preferred that this be a
>>> constraint violation, and I would expect any decent implementation of
>>> C99 or later to issue the diagnostic message that would be mandatory if
>>> it were a constraint violation - in my opinion, that possibility is the
>>> only thing that makes this feature worthwhile.  I think that the reason
>>> why it cannot be made a constraint violation is that f(p) is also a
>>> violation of the same rule, and unlike f(small_array), it's not in
>>> general easy for a compiler to identify the fact that an arbitrary
>>> pointer points at location which violates this rule.
>>
>> But surely if g were defined:
>>
>> 	void g(int array[3]);
>>
>> Then g(small_array) would still be a constraint violation?
>
> No.  See the first part of 6.7.6.3p7:  "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."
>
> This means that the declaration is adjusted to
>     void g(int *array);
>
> It might not be obvious from the above wording, but for multidimensional
> arrays, this only affects the leading dimension of the array.
>
>> ...  Or is it 
>> defined behaviour to call g(small_array), and only becomes undefined if 
>> g() accesses array[2] ?
>
> Correct.

Someone might want to tell James that the behavior of this call
is undefined behavior no matter which elements of 'array' g()
accesses (eg, even if g() function body is empty).  6.7.6.3 p7.

[toc] | [prev] | [next] | [standalone]


#69724

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-06 18:59 -0700
Message-ID<kfnio7nng50.fsf@x-alumni2.alumni.caltech.edu>
In reply to#68699
David Brown <david.brown@hesbynett.no> writes:

> On 30/08/15 18:18, James Kuyper wrote:
>> On 08/30/2015 10:56 AM, David Brown wrote:
>>> On 29/08/15 23:08, James Kuyper wrote:
>>>
>>>> The following use of "static" is new in C99, and can only occur in the
>>>> leading dimension of a function parameter declared as an array:
>>>> "If the keyword static also appears within the [ and ] of the array type
>>>> derivation, then for each call to the function, the value of the
>>>> corresponding actual argument shall provide access to the first element
>>>> of an array with at least as many elements as specified by the size
>>>> expression."  6.7.6.3p7
>>>>
>>>> This obviously should have no counterpart in K&R C.
>>>
>>> This last use of "static" is completely new to me.  I can see the
>>> corresponding paragraph in the C11 standards (since that's the one I
>>> have handy), but I can't figure out what it means or what it is for.

It's pretty disappointing that you haven't gotten better replies
to your query on this.  The replies I've seen aren't very helpful
and get several things wrong.  Let's see if we can do a little
better here.

First, the point of using 'static' in this way is to allow some
optimizations to take place that wouldn't be allowed otherwise.
If we have a function definition like this

    void
    foo( int x[ static 100 ] ){
        ...
    }

then when compiling foo() the compiler is allowed to assume
that the pointer 'x' (which is a pointer, because of rules
about function parameter types) points to an array with at
least 100 elements.  That proviso enables the code to, eg,
initiate some prefetching if that seems like a good thing to
do.

Second, using 'static' in this way resembles how 'restrict' works
with pointer parameters.  The 'static'-ness of the array is not
part of the type of the function, and it doesn't have to be the
same in declarations as it is in the definition.  Normally any
functions defined with this use of 'static' will also have
'static' in their declarations, but doing that is really just for
documentation, not anything else.

Third, what happens with such 'static' parameters when compiling
calls to the function is analogous to compiling calls to
functions whose parameters have 'restrict' qualifiers.  It
doesn't imply any extra checking or constraint validation.  (Of
course implementations are free to do extra checking if they
want, but none is required.)  What using 'static' does is
impose an additional /un/checked requirement that any actual
argument have at least that many elements;  not meeting that
requirement makes the call be undefined behavior.

Incidentally, note that the length parameter is also not part of
the parameter type, and hence may be different between a function 
declaration and its definition.  Thus we might have

    int foo( int x[ static 200 ] );

    ...

    int
    foo( int x[ static 100 ] ){
        ...
    }

which the Standard allows.  What I believe is true in such
cases is that both conditions must be met, ie, the larger
value is the one that the compiler may assume.  However
the Standard is not completely clear on the matter, so for
safety the different values should all agree (and probably
expect the value on the function /definition/ to take
precedence, although again the Standard isn't completely
clear on the matter).

>> Given:
>>
>>      void f(int array[static 3]);
>>      int large_array[6];
>>      int small_array[2];
>>      int *p = small_array;
>>
>> then f(large_array) is fine, because large_array has more than 3
>> elements.  However, f(small_array) violates a "shall" that occurs outside
>> of a constraint, because small_array has fewer than 3 elements.  The
>> behavior is therefore undefined.  I would have preferred that this be a
>> constraint violation, and I would expect any decent implementation of
>> C99 or later to issue the diagnostic message that would be mandatory if
>> it were a constraint violation - in my opinion, that possibility is the
>> only thing that makes this feature worthwhile.  I think that the reason
>> why it cannot be made a constraint violation is that f(p) is also a
>> violation of the same rule, and unlike f(small_array), it's not in
>> general easy for a compiler to identify the fact that an arbitrary
>> pointer points at location which violates this rule.
>
> But surely if g were defined:
>
>     void g(int array[3]);
>
> Then g(small_array) would still be a constraint violation?

No, it isn't.

> Or is it
> defined behaviour to call g(small_array), and only becomes undefined
> if g() accesses array[2] ?

No.  A call like g(small_array) is undefined behavior whether
code in g() accesses that parameter or not.

> It seems to me that even without the "static", g is asking for a
> parameter with particular characteristics, and calling g(small_array)
> is breaking that requirement.

That can be true, depending on what code is present in g().
The point of using 'static' is to provide the compiler with
extra information so it doesn't have to do any code
analysis to exploit the optimization possibility.  Again,
like 'restrict'.

> It also seems to me to be a /really/ odd choice to make this another
> use of the "static" keyword.

It's sort of an inside joke by the WG14 members.  I myself don't
find it so bad, although I understand why some people find it
odd.

> If a keyword is needed here (I think the
> "static" behaviour is the only sensible one, and should be the case
> without the keyword), then I would go for a new keyword such as
> "__I_really_mean_it" :-)

Personally I think reusing 'static' is a better choice here.
Anyway it's a done deal.

> Is this a use of "static" that you have seen in real code?  Is
> it used much?

Now that you know what it's for, especially with your general
concerns for performance, I expect you will finds lots of
occasions where it might be useful.

[toc] | [prev] | [next] | [standalone]


#69744

FromDavid Brown <david.brown@hesbynett.no>
Date2015-09-07 10:25 +0200
Message-ID<msjhi9$2d9$1@dont-email.me>
In reply to#69724
On 07/09/15 03:59, Tim Rentsch wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 30/08/15 18:18, James Kuyper wrote:
>>> On 08/30/2015 10:56 AM, David Brown wrote:
>>>> On 29/08/15 23:08, James Kuyper wrote:
>>>>
>>>>> The following use of "static" is new in C99, and can only occur in the
>>>>> leading dimension of a function parameter declared as an array:
>>>>> "If the keyword static also appears within the [ and ] of the array type
>>>>> derivation, then for each call to the function, the value of the
>>>>> corresponding actual argument shall provide access to the first element
>>>>> of an array with at least as many elements as specified by the size
>>>>> expression."  6.7.6.3p7
>>>>>
>>>>> This obviously should have no counterpart in K&R C.
>>>>
>>>> This last use of "static" is completely new to me.  I can see the
>>>> corresponding paragraph in the C11 standards (since that's the one I
>>>> have handy), but I can't figure out what it means or what it is for.
> 
> It's pretty disappointing that you haven't gotten better replies
> to your query on this.  The replies I've seen aren't very helpful
> and get several things wrong.  Let's see if we can do a little
> better here.

I'm ready to take notes.

> 
> First, the point of using 'static' in this way is to allow some
> optimizations to take place that wouldn't be allowed otherwise.
> If we have a function definition like this
> 
>     void
>     foo( int x[ static 100 ] ){
>         ...
>     }
> 
> then when compiling foo() the compiler is allowed to assume
> that the pointer 'x' (which is a pointer, because of rules
> about function parameter types) points to an array with at
> least 100 elements.  That proviso enables the code to, eg,
> initiate some prefetching if that seems like a good thing to
> do.

I assume that as well as optimising here, the compiler can also use the
information for extra checking.  (However I am a little disappointed
that a quick test with gcc 4.9 does not seem to give any warnings when
this foo is called with an array of less than 100.)

> 
> Second, using 'static' in this way resembles how 'restrict' works
> with pointer parameters.  The 'static'-ness of the array is not
> part of the type of the function, and it doesn't have to be the
> same in declarations as it is in the definition.  Normally any
> functions defined with this use of 'static' will also have
> 'static' in their declarations, but doing that is really just for
> documentation, not anything else.

I am a big fan of such documentation - and I am very strict about
declarations and definitions matching exactly (stricter than the
compiler requires).

> 
> Third, what happens with such 'static' parameters when compiling
> calls to the function is analogous to compiling calls to
> functions whose parameters have 'restrict' qualifiers.  It
> doesn't imply any extra checking or constraint validation.  (Of
> course implementations are free to do extra checking if they
> want, but none is required.)  What using 'static' does is
> impose an additional /un/checked requirement that any actual
> argument have at least that many elements;  not meeting that
> requirement makes the call be undefined behavior.

Fair enough.

It is nice if the compiler (or possibly other static error checkers) can
check it.

> 
> Incidentally, note that the length parameter is also not part of
> the parameter type, and hence may be different between a function 
> declaration and its definition.  Thus we might have
> 
>     int foo( int x[ static 200 ] );
> 
>     ...
> 
>     int
>     foo( int x[ static 100 ] ){
>         ...
>     }
> 
> which the Standard allows.  What I believe is true in such
> cases is that both conditions must be met, ie, the larger
> value is the one that the compiler may assume.  However
> the Standard is not completely clear on the matter, so for
> safety the different values should all agree (and probably
> expect the value on the function /definition/ to take
> precedence, although again the Standard isn't completely
> clear on the matter).

All in all, it sounds like a nice idea, but a little disappointing in
practice.  I would have preferred the standards (and compiler) to be a
lot stricter in checking such things.  I can understand that for
backward compatibility, and the way arrays are handled and passed in C,
that it is hard for the compiler to enforce or assume anything about
array parameters that are not declared with this "static".  But I had
hoped that it could do more with the added "static".

As far as I can tell, the explicit undefined behaviour gives the
compiler a freer hand for optimisation, and that's about it.  (Compilers
/could/ implement a little more static error checking, but extrapolating
wildly from my sample of 1 test, they apparently don't do so.  Perhaps
it's simply because this use of "static" is not common, so it is not a
feature that the gcc folk have implemented.)

As for documentation - and therefore "manual" enforcement, I don't see
that the use of "static" adds anything, at least for my own code.  If I
declare a function to have a parameter "int x[100]", then it is clear to
me that this function wants an array of at least 100 int's.  The
"static" is superfluous from the documentation viewpoint.

> 
>>> Given:
>>>
>>>      void f(int array[static 3]);
>>>      int large_array[6];
>>>      int small_array[2];
>>>      int *p = small_array;
>>>
>>> then f(large_array) is fine, because large_array has more than 3
>>> elements.  However, f(small_array) violates a "shall" that occurs outside
>>> of a constraint, because small_array has fewer than 3 elements.  The
>>> behavior is therefore undefined.  I would have preferred that this be a
>>> constraint violation, and I would expect any decent implementation of
>>> C99 or later to issue the diagnostic message that would be mandatory if
>>> it were a constraint violation - in my opinion, that possibility is the
>>> only thing that makes this feature worthwhile.  I think that the reason
>>> why it cannot be made a constraint violation is that f(p) is also a
>>> violation of the same rule, and unlike f(small_array), it's not in
>>> general easy for a compiler to identify the fact that an arbitrary
>>> pointer points at location which violates this rule.
>>
>> But surely if g were defined:
>>
>>     void g(int array[3]);
>>
>> Then g(small_array) would still be a constraint violation?
> 
> No, it isn't.

OK.  So it is a "violation" of the documented use of the function, but
not of the C code, and the compiler cannot check the size of the array,
nor make assumptions about it for code generation.

> 
>> Or is it
>> defined behaviour to call g(small_array), and only becomes undefined
>> if g() accesses array[2] ?
> 
> No.  A call like g(small_array) is undefined behavior whether
> code in g() accesses that parameter or not.

OK...

So why is the "static" needed at all?  The compiler can already optimise
g on the assumption that the passed parameter has at least 3 elements,
as giving it less than 3 elements would be undefined behaviour.

Section 6.7.6.3 p 7 (C11, N1570) specifically says that with the
"static", each call to the function must pass an array with at least as
many elements as declared.  But I can't find an indication that this
also applies without the "static".  The final note at the end of the
examples in 6.7.6.3 says:

<quote>

The following are all compatible function prototype declarators:

void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);

(Note that the last declaration also specifies that the argument
corresponding to a in any call to f must be a non-null pointer to the
first of at least three arrays of 5 doubles, which the others do not.)

</quote>





> 
>> It seems to me that even without the "static", g is asking for a
>> parameter with particular characteristics, and calling g(small_array)
>> is breaking that requirement.
> 
> That can be true, depending on what code is present in g().
> The point of using 'static' is to provide the compiler with
> extra information so it doesn't have to do any code
> analysis to exploit the optimization possibility.  Again,
> like 'restrict'.

"restrict" can give the compiler information that it often can't
otherwise get from analysis (at least, not without some sort of
whole-program optimisation).  But if you are correct that calling
g(small_array) above is already undefined behaviour even without g
accessing array[2], then it already has the information that "static"
would give it.

> 
>> It also seems to me to be a /really/ odd choice to make this another
>> use of the "static" keyword.
> 
> It's sort of an inside joke by the WG14 members.  I myself don't
> find it so bad, although I understand why some people find it
> odd.
> 
>> If a keyword is needed here (I think the
>> "static" behaviour is the only sensible one, and should be the case
>> without the keyword), then I would go for a new keyword such as
>> "__I_really_mean_it" :-)
> 
> Personally I think reusing 'static' is a better choice here.
> Anyway it's a done deal.

Indeed.

> 
>> Is this a use of "static" that you have seen in real code?  Is
>> it used much?
> 
> Now that you know what it's for, especially with your general
> concerns for performance, I expect you will finds lots of
> occasions where it might be useful.
> 

I don't actually pass array parameters around that much, and when I do
they are often part of a struct anyway.  And while performance and
optimisation opportunities are often a concern (smaller and faster code
can mean smaller and cheaper microcontrollers, or lower power or less
electrical noise), I see it as unlikely that this "static" qualifier
will actually lead to faster code on the types of cpus and with the
types of code that I use.  Still, I am always on the lookout for new
tools in the toolbox, especially if it can (in theory at least) lead to
more precise specification and more static error analysis.

So many thanks for the detailed explanation, and I hope you can clear up
my confusion about the undefined behaviour in g(small_array) above.

[toc] | [prev] | [next] | [standalone]


#69749

FromKeith Thompson <kst-u@mib.org>
Date2015-09-07 01:59 -0700
Message-ID<lny4gisiz6.fsf@kst-u.example.com>
In reply to#69744
David Brown <david.brown@hesbynett.no> writes:
> On 07/09/15 03:59, Tim Rentsch wrote:
>> David Brown <david.brown@hesbynett.no> writes:

[...]

> As for documentation - and therefore "manual" enforcement, I don't see
> that the use of "static" adds anything, at least for my own code.  If I
> declare a function to have a parameter "int x[100]", then it is clear to
> me that this function wants an array of at least 100 int's.  The
> "static" is superfluous from the documentation viewpoint.

The problem is that these three declarations:

    void func(int x[100]);
    void func(int x[]);
    void func(int *x);

all mean exactly the same thing, and the 100 is quietly ignored.  If you
write the first, it's obvious that you *intended* x to point the first
element of an array with at least 100 elements -- but it's equally
obvious to anyone who knows C sufficiently well that you haven't
expressed that intent to the compiler.

It would have been nice if
    void func(int x[100]);
had meant what
    void func(int x[static 100]);
means, but it was too late to change the existing meaning.

[...]

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

[toc] | [prev] | [next] | [standalone]


#69756

FromDavid Brown <david.brown@hesbynett.no>
Date2015-09-07 12:22 +0200
Message-ID<msjodd$qjn$1@dont-email.me>
In reply to#69749
On 07/09/15 10:59, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 07/09/15 03:59, Tim Rentsch wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
> 
> [...]
> 
>> As for documentation - and therefore "manual" enforcement, I don't see
>> that the use of "static" adds anything, at least for my own code.  If I
>> declare a function to have a parameter "int x[100]", then it is clear to
>> me that this function wants an array of at least 100 int's.  The
>> "static" is superfluous from the documentation viewpoint.
> 
> The problem is that these three declarations:
> 
>     void func(int x[100]);
>     void func(int x[]);
>     void func(int *x);
> 
> all mean exactly the same thing, and the 100 is quietly ignored.  

They all mean the same thing to the C compiler, which quietly ignores
the 100 - but they should not mean the same thing to a human programmer,
and they may not mean the same thing to static error analysis tools.

> If you
> write the first, it's obvious that you *intended* x to point the first
> element of an array with at least 100 elements -- but it's equally
> obvious to anyone who knows C sufficiently well that you haven't
> expressed that intent to the compiler.

True.

> 
> It would have been nice if
>     void func(int x[100]);
> had meant what
>     void func(int x[static 100]);
> means, but it was too late to change the existing meaning.
> 

Indeed.

However, as far as I can see, "void func(int x[static 100])" means
almost exactly the same to the compiler as "void func(int x[100])".  The
compiler is quite happy to view the declaration with the "static" as
being entirely compatible with those you listed without the "static",
and it is quite happy to have multiple declarations of the same function
with different static sizes of the array.

[toc] | [prev] | [next] | [standalone]


#69822

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-09-07 13:04 -0400
Message-ID<55EDC3A8.3000804@verizon.net>
In reply to#69756
On 09/07/2015 06:22 AM, David Brown wrote:
...
> However, as far as I can see, "void func(int x[static 100])" means
> almost exactly the same to the compiler as "void func(int x[100])".  The
> compiler is quite happy to view the declaration with the "static" as
> being entirely compatible with those you listed without the "static",
> and it is quite happy to have multiple declarations of the same function
> with different static sizes of the array.

The key difference is that without the "static", there's undefined
behavior only if the code for func(p) tries to access x[i] for values of
i such that p[i] would have undefined behavior. With "static 100", it's
also undefined behavior to call the function with a pointer to less than
100 consecutive accessible 'int' objects, regardless of what func()
actually does with x. I don't fully understand what opportunities this
opens up for optimization, but if Tim says there are some, I'm willing
to guess that he might be right. But for me, the only useful aspect of
this feature is one not guaranteed by the standard - the possibility of
getting a warning message during compilation of the program.

[toc] | [prev] | [next] | [standalone]


Page 1 of 5  [1] 2 3 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web