Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #68648 > unrolled thread
| Started by | fir <profesor.fir@gmail.com> |
|---|---|
| First post | 2015-08-29 11:40 -0700 |
| Last post | 2015-09-05 01:24 +0000 |
| Articles | 20 on this page of 83 — 20 participants |
Back to article view | Back to comp.lang.c
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 →
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2015-08-29 11:40 -0700 |
| Subject | who 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]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-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]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2015-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]
| From | David Kleinecke <dkleinecke@gmail.com> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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