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 2 of 5 — ← Prev page 1 [2] 3 4 5 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-09-07 21:25 +0200 |
| Message-ID | <msko74$ueg$1@dont-email.me> |
| In reply to | #69822 |
On 07/09/15 19:04, James Kuyper wrote: > 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. That's what I thought was the case, but then Tim confused me by saying that without the "static" there is still undefined behaviour if you call the function with a pointer to less than 100 ints, even if the function does not attempt to access them. If I was merely mistaken in my interpretation of Tim (or if Time made a mistake in his description), then I believe I understand the point. > 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. Tim's example was that the compiler could issue cache prefetches for data without worrying about whether or not it was accessible. Usually prefetches are not dangerous operations - even if, for example, the cpu's MMU was set up to trap on accesses beyond the array then a prefetch would typically not trap until the addresses are accessed by non-prefetch instructions. But maybe on some cpus it /would/ trap. However, other possibilities include loop unrolling, converting the loop to run backwards (if that happened to be more efficient), or loading data in larger lumps into SIMD registers. I doubt if there are many opportunities to make significant speed improvements, but there always some. > 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. > I agree - that's what would be most useful for me. That is why I find it particularly disappointing that not only does the standard not specify any diagnostics, it does not even require the code to be consistent in the size of the static array parameters.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-09-07 15:47 -0400 |
| Message-ID | <55EDE9D6.9090204@verizon.net> |
| In reply to | #69834 |
On 09/07/2015 03:25 PM, David Brown wrote: > On 07/09/15 19:04, James Kuyper wrote: >> 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. > > That's what I thought was the case, but then Tim confused me by saying > that without the "static" there is still undefined behaviour if you call > the function with a pointer to less than 100 ints, even if the function > does not attempt to access them. ... Could you cite text written by him that you believe expresses that opinion? I went to Google Groups to review his conversations with you, and didn't see anything like that; but it's a fairly large amount of text, and I might have missed something.
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-09-07 13:27 -0700 |
| Message-ID | <MPG.30579326e51a467e5c@news.eternal-september.org> |
| In reply to | #69838 |
James Kuyper wrote: > On 09/07/2015 03:25 PM, David Brown wrote: > > On 07/09/15 19:04, James Kuyper wrote: > >> 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. > > > > That's what I thought was the case, but then Tim confused me by saying > > that without the "static" there is still undefined behaviour if you call > > the function with a pointer to less than 100 ints, even if the function > > does not attempt to access them. ... > > Could you cite text written by him that you believe expresses that > opinion? I went to Google Groups to review his conversations with you, > and didn't see anything like that; but it's a fairly large amount of > text, and I might have missed something. Here's the place: 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: > >> 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. My guess is that when Tim wrote that, he meant to refer to f rather than g. If not, then I'm confused too.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-09-07 17:31 -0400 |
| Message-ID | <55EE0214.1080106@verizon.net> |
| In reply to | #69846 |
On 09/07/2015 04:27 PM, Philip Lantz wrote: ... > 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: >>>> Given: >>>> >>>> void f(int array[static 3]); >>>> int large_array[6]; >>>> int small_array[2]; ... >>> 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. > > My guess is that when Tim wrote that, he meant to refer to f rather than > g. If not, then I'm confused too. I read precisely that paragraph, looking for precisely that kind of answer, and didn't notice that Tim gave it. Proofreading is not one of my strong points. I gave David a contrary answer to the same question, and now that I've looked on Google Groups, I see that Tim disagreed with me: > Someone might want to tell James ... The reason he put it that way was that he knows I've got him kill-filed, even though he's not a troll and is very knowledgeable about C, because I've found that we often tend to get stuck in long unproductive arguments. He was hoping someone would quote his message so I could see it, but nobody did. I hope that this doesn't turn into one of those arguments. > ... 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. 6.7.6.3p7 indicates that "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.". This is "... a shall ... that appears outside of a constraint ...", so "... the behavior is undefined." (4p2) when it is violated, but I don't see how that applies to g(), since "... the keyword static ... " does NOT appear "... within the [ and ] of the array type derivation ..." in the declaration of g().
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-09-08 09:16 +0200 |
| Message-ID | <msm1tb$pna$1@dont-email.me> |
| In reply to | #69850 |
On 07/09/15 23:31, James Kuyper wrote: > On 09/07/2015 04:27 PM, Philip Lantz wrote: > ... >> 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: >>>>> Given: >>>>> >>>>> void f(int array[static 3]); >>>>> int large_array[6]; >>>>> int small_array[2]; > ... >>>> 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. >> >> My guess is that when Tim wrote that, he meant to refer to f rather than >> g. If not, then I'm confused too. > > I read precisely that paragraph, looking for precisely that kind of > answer, and didn't notice that Tim gave it. Proofreading is not one of > my strong points. > > I gave David a contrary answer to the same question, and now that I've > looked on Google Groups, I see that Tim disagreed with me: > >> Someone might want to tell James ... > > The reason he put it that way was that he knows I've got him kill-filed, > even though he's not a troll and is very knowledgeable about C, because > I've found that we often tend to get stuck in long unproductive > arguments. He was hoping someone would quote his message so I could see > it, but nobody did. I hope that this doesn't turn into one of those > arguments. > I believe it is all sorted out now, and there is no need for a long argument. (Not that people in c.l.c. need a reason for having long arguments...). I have certainly learning something new from this thread, especially thanks to you and Tim. I am not sure this use of "static" will find much use in my own code - it does not offer the strong checking that it could do, but it is good to know about it.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-09-07 13:27 -0700 |
| Message-ID | <lntwr6rn4m.fsf@kst-u.example.com> |
| In reply to | #69834 |
David Brown <david.brown@hesbynett.no> writes:
> On 07/09/15 19:04, James Kuyper wrote:
[...]
>> 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.
>
> That's what I thought was the case, but then Tim confused me by saying
> that without the "static" there is still undefined behaviour if you call
> the function with a pointer to less than 100 ints, even if the function
> does not attempt to access them. If I was merely mistaken in my
> interpretation of Tim (or if Time made a mistake in his description),
> then I believe I understand the point.
I don't know whether the mistake was yours or Tim's, but that particular
undefined behavior occurs only when the "static" keyword is present.
[...]
> I agree - that's what would be most useful for me. That is why I find
> it particularly disappointing that not only does the standard not
> specify any diagnostics, it does not even require the code to be
> consistent in the size of the static array parameters.
A diagnostic cannot be required in all cases, since the size of the
array is not necessarily known at compile time:
void func(int arr[static 100]);
int *ptr = malloc(N);
func(ptr);
In such cases, the standard generally leaves it to individual compilers
to issue warnings when they can.
--
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-08 09:12 +0200 |
| Message-ID | <msm1lg$p08$1@dont-email.me> |
| In reply to | #69845 |
On 07/09/15 22:27, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 07/09/15 19:04, James Kuyper wrote: > [...] >>> 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. >> >> That's what I thought was the case, but then Tim confused me by saying >> that without the "static" there is still undefined behaviour if you call >> the function with a pointer to less than 100 ints, even if the function >> does not attempt to access them. If I was merely mistaken in my >> interpretation of Tim (or if Time made a mistake in his description), >> then I believe I understand the point. > > I don't know whether the mistake was yours or Tim's, but that particular > undefined behavior occurs only when the "static" keyword is present. > > [...] > >> I agree - that's what would be most useful for me. That is why I find >> it particularly disappointing that not only does the standard not >> specify any diagnostics, it does not even require the code to be >> consistent in the size of the static array parameters. > > A diagnostic cannot be required in all cases, since the size of the > array is not necessarily known at compile time: > > void func(int arr[static 100]); > int *ptr = malloc(N); > func(ptr); > > In such cases, the standard generally leaves it to individual compilers > to issue warnings when they can. > I agree that the compiler cannot see such cases. But it certainly /can/ see a case like this: void func(int arr[static 100]); void func(int arr[static 200]); void func(int arr[300]); All the numbers involved have to be available at compile time. Yet not only are diagnostics not mandatory, the code is actually perfectly acceptable by the standards. That is a missed opportunity by the standards folk, IMHO. Of course, compilers can offer addition (non-default) warning options to help spot that kind of thing too.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-09-07 16:06 -0700 |
| Message-ID | <kfnsi6pn81d.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #69834 |
David Brown <david.brown@hesbynett.no> writes:
> On 07/09/15 19:04, James Kuyper wrote:
>> 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.
>
> That's what I thought was the case, but then Tim confused me by saying
> that without the "static" there is still undefined behaviour if you
> call the function with a pointer to less than 100 ints, even if the
> function does not attempt to access them. [snip]
I need to give a mea culpa here. I overlooked that the only
declaration of g() lacked the static attribute. I have a partial
explanation for why that may have happened, but it was a mistake
on my part. My apologies to James, to David, and also anyone
else who may have been mislead or confused. Also I hope someone
will arrange for James to get a copy of my apology.
Now here is the original context:
[taken from a posting by David Brown]
> 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.
Since the discussion was about the static attribute, I assumed
that the parameter of g() was marked in this way, despite (or
overlooking) the given declaration. This impression was further
led astray by the paragraph that starts "It seems to me that even
without the "static", g is asking for ...", which sounds like it
is offering a contrast to the previous paragraph, ie, that g()
/did/ have static for that question. To be clear on the point,
if all the declarations for g() don't have 'static' as part of
the first parameter declaration, then g(small_array) is indeed
defined behavior, and the behavior is undefined only if accesses
are made outside the actual bounds of the array argument (eg,
array[2]).
Also, I think it's important to add another remark. This isn't
meant to excuse my earlier oversight, but I think it's important
to note here. If g() is declared as above, and various files
are compiled using that declaration, but where g() is defined
in another translation unit, it is defined like so:
void
g( int array[static 3] ){
...
}
then calling g(small_array) /is/ undefined behavior, even though
the "static-ness" of that parameter is not visible at those call
sites. In fact it goes farther than that. As I read the
Standard, if /any/ declaration of g() gives a 'static' attribute,
it's the same as if they all did. Note that this is different
than how, eg, 'restrict' or 'const', behaves: with qualifiers,
the governing occurrence is the function definition, and nothing
else counts. But how 'static' works is described slightly
differently, and appears to apply no matter which declaration it
occurs in. (I admit this question is not addressed as clearly as
I would like, ie, I think reasonable arguments could be made with
different conclusions. IMO the interpretation I have given is
the most natural one, but in the interest of fairness I have to
add that other interpretations are plausibly defensible.) So the
phrasing of questions related to array "static-ness" is more
delicate than it is for qualifiers like 'restrict' or 'const.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-09-08 09:08 +0200 |
| Message-ID | <msm1e3$o8n$1@dont-email.me> |
| In reply to | #69855 |
On 08/09/15 01:06, Tim Rentsch wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 07/09/15 19:04, James Kuyper wrote:
>>> 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.
>>
>> That's what I thought was the case, but then Tim confused me by saying
>> that without the "static" there is still undefined behaviour if you
>> call the function with a pointer to less than 100 ints, even if the
>> function does not attempt to access them. [snip]
>
> I need to give a mea culpa here. I overlooked that the only
> declaration of g() lacked the static attribute. I have a partial
> explanation for why that may have happened, but it was a mistake
> on my part. My apologies to James, to David, and also anyone
> else who may have been mislead or confused. Also I hope someone
> will arrange for James to get a copy of my apology.
>
> Now here is the original context:
>
> [taken from a posting by David Brown]
>
>> 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.
>
> Since the discussion was about the static attribute, I assumed
> that the parameter of g() was marked in this way, despite (or
> overlooking) the given declaration. This impression was further
> led astray by the paragraph that starts "It seems to me that even
> without the "static", g is asking for ...", which sounds like it
> is offering a contrast to the previous paragraph, ie, that g()
> /did/ have static for that question. To be clear on the point,
> if all the declarations for g() don't have 'static' as part of
> the first parameter declaration, then g(small_array) is indeed
> defined behavior, and the behavior is undefined only if accesses
> are made outside the actual bounds of the array argument (eg,
> array[2]).
>
> Also, I think it's important to add another remark. This isn't
> meant to excuse my earlier oversight, but I think it's important
> to note here. If g() is declared as above, and various files
> are compiled using that declaration, but where g() is defined
> in another translation unit, it is defined like so:
>
> void
> g( int array[static 3] ){
> ...
> }
>
> then calling g(small_array) /is/ undefined behavior, even though
> the "static-ness" of that parameter is not visible at those call
> sites. In fact it goes farther than that. As I read the
> Standard, if /any/ declaration of g() gives a 'static' attribute,
> it's the same as if they all did. Note that this is different
> than how, eg, 'restrict' or 'const', behaves: with qualifiers,
> the governing occurrence is the function definition, and nothing
> else counts. But how 'static' works is described slightly
> differently, and appears to apply no matter which declaration it
> occurs in. (I admit this question is not addressed as clearly as
> I would like, ie, I think reasonable arguments could be made with
> different conclusions. IMO the interpretation I have given is
> the most natural one, but in the interest of fairness I have to
> add that other interpretations are plausibly defensible.) So the
> phrasing of questions related to array "static-ness" is more
> delicate than it is for qualifiers like 'restrict' or 'const.
>
(I'm quoting everything here without snipping, to make sure everyone
sees it.)
Thanks for clearing that up, Tim. I've missed enough small details in
posts about the "letter of the law" in C standards to know how easy it
is. I'm grateful that you took the time to sort out the confusion and
explain it all.
Mismatches between function declarations and function definitions should
not occur in my code - I am very strict about how this is done, and use
compiler warnings to enforce my rules as tightly as possible. But it is
useful to know of such possibilities, especially as C accepts small but
significant variations in the function declarations as being compatible
(a poor design decision, IMHO, but one we have to live with).
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-09-12 11:29 -0700 |
| Message-ID | <kfnfv2jij8k.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #69873 |
David Brown <david.brown@hesbynett.no> writes: > On 08/09/15 01:06, Tim Rentsch wrote: >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 07/09/15 19:04, James Kuyper wrote: >>>> On 09/07/2015 06:22 AM, David Brown wrote: > [snip] > > Thanks for clearing that up, Tim. I'm glad it all got sorted out. > I've missed enough small details in posts about the "letter of > the law" in C standards to know how easy it is. Here there were a variety of forces that worked together to mislead me. I make a real effort not to make mistakes like this (well, or any mistakes really, but these especially) but in this case I was led astray. I resolve to do better next time. > I'm grateful that you took the time to sort out the confusion > and explain it all. Thank you, I appreciate that. I may also go back and give some brief responses to your longer post upthread.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-09-08 10:18 -0700 |
| Message-ID | <ln4mj4sucl.fsf@kst-u.example.com> |
| In reply to | #69855 |
James: See the parent article.
Tim Rentsch <txr@alumni.caltech.edu> writes:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 07/09/15 19:04, James Kuyper wrote:
>>> 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.
>>
>> That's what I thought was the case, but then Tim confused me by saying
>> that without the "static" there is still undefined behaviour if you
>> call the function with a pointer to less than 100 ints, even if the
>> function does not attempt to access them. [snip]
>
> I need to give a mea culpa here. I overlooked that the only
> declaration of g() lacked the static attribute. I have a partial
> explanation for why that may have happened, but it was a mistake
> on my part. My apologies to James, to David, and also anyone
> else who may have been mislead or confused. Also I hope someone
> will arrange for James to get a copy of my apology.
[...]
--
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 | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-09-08 13:28 -0400 |
| Message-ID | <msn5on$40e$1@dont-email.me> |
| In reply to | #69943 |
On 09/08/2015 01:18 PM, Keith Thompson wrote: > James: See the parent article. > > Tim Rentsch <txr@alumni.caltech.edu> writes: >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 07/09/15 19:04, James Kuyper wrote: >>>> 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. >>> >>> That's what I thought was the case, but then Tim confused me by saying >>> that without the "static" there is still undefined behaviour if you >>> call the function with a pointer to less than 100 ints, even if the >>> function does not attempt to access them. [snip] >> >> I need to give a mea culpa here. I overlooked that the only >> declaration of g() lacked the static attribute. I have a partial >> explanation for why that may have happened, but it was a mistake >> on my part. My apologies to James, to David, and also anyone >> else who may have been mislead or confused. Also I hope someone >> will arrange for James to get a copy of my apology. Received, and accepted. I make that same kind of mistake all the time. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-09-11 10:07 -0700 |
| Message-ID | <kfnio7gkhp4.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #69943 |
Keith Thompson <kst-u@mib.org> writes: > James: See the parent article. > > Tim Rentsch <txr@alumni.caltech.edu> writes: >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 07/09/15 19:04, James Kuyper wrote: >>>> 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. >>> >>> That's what I thought was the case, but then Tim confused me by saying >>> that without the "static" there is still undefined behaviour if you >>> call the function with a pointer to less than 100 ints, even if the >>> function does not attempt to access them. [snip] >> >> I need to give a mea culpa here. I overlooked that the only >> declaration of g() lacked the static attribute. I have a partial >> explanation for why that may have happened, but it was a mistake >> on my part. My apologies to James, to David, and also anyone >> else who may have been mislead or confused. Also I hope someone >> will arrange for James to get a copy of my apology. > > [...] Thank you for reposting this.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-09-12 12:30 -0700 |
| Message-ID | <kfnbnd7iget.fsf@x-alumni2.alumni.caltech.edu> |
| 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:
>>
>>> 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.
I'm following up here after posting my downstream response
correcting the mistake I made. I am not repeating that but there
are some other comments that may be useful.
>> 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.)
There are two problems with the idea that using the 'static'
attribute this way is (even partly) for compile-time error
reporting. One, because the 'static' can be there on a
definition but not on a declaration, there is no guarantee that
the call site knows to do the check. Two, like most conditions
that depend on run-time values, what we're interested in cannot
be checked in the general case. In all such cases (AFAIAA), the
C standard relegates these to undefined behavior, leaving the
question of any compile-time diagnostics as a QOI matter, not
part of the official language definition. IMO this choice is
the right decision for C (and I prefer not to consider the
question more generally, at least as far as comp.lang.c goes).
>> 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).
I agree everything should be in sync. My preference, when
possible, is to auto-generate the appropriate declarations based
on the corresponding definitions. If you can get other people
to buy into that, I find it enormously effective in terms of
both productivity and confidence in the result.
>> 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.
Any diagnostic of this sort (ie, which is undecidable in the
general case) comes with problems - false positives, false
negatives, or possibly both. Also, something that may not
have occured to you, the array bound after the 'static' might
not be a constant. C99 has variable length arrays, which
means that this
int
foo( int n, int v[ static n ] ){
...
}
is legal. Cases like this are much harder to check.
I sympathize with your desire to have diagnostics produced, where
possible. But this is a QOI concern, not a language concern, and
ANSI/ISO made a deliberate choice to not address QOI matters in
the C standard. Because of that, it doesn't surprise me, or
disappoint me, that the possibility of doing such a check for
'static' parameters was ignored in defining the C language.
>> 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 explained above why the Standard doesn't address it. As for
compilers, of course they could, but I expect there isn't much
call to do so, especially since there is no guarantee that the
declarations used match the definitions.
> 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".
The problem is undecidable. Anything that might be done is
a compromise that some people will be happy with and others
will not. Unless the user community cries out for something
I don't think anything will be done, especially since the
problem is not just undecidable but difficult to do even
fairly well. I believe the perception is that the ROI is
just not very high.
> As far as I can tell, the explicit undefined behaviour gives the
> compiler a freer hand for optimisation, and that's about it.
Yes, that is it, exactly 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.)
And that it is hard to do well.
> 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.
I think you might want to re-think this position. By way of
analogy, there's a difference between saying "I'm not going
to drive faster than 35 miles per hour" and saying "I'm not
going to drive faster than 35 miles per hour, and if I do
I agree to pay you as much money as you ask for." Without
the 'static', there may be some cases, eg based on the values
of other parameters, that are still okay. With the 'static',
any transgression is irredeemable. You may choose not to
make these kinds of distinctions, but other people might,
and IMO it is worth keeping that in mind.
> [here was the part that I already addressed]
>
>>> 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.
This statement surprised me. Do you mean you hardly ever
pass pointer values as function parameters? Or types
like 'char *'? Both of these cases have some potential
benefit using 'static'.
> 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.
A pointer parameter declared like 'T x[ static 1 ]' is one that
the compiler may assume is non-null, which may very well help
code generation even on very low-end CPU's. (Disclaimer: I
am certainly not an expect on optimization, but I see gcc do
some amazing things based on such "facts", so it seems fair
to say that the scenario is at least plausible.)
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-09-13 15:48 +0200 |
| Message-ID | <mt3uoj$9s6$1@dont-email.me> |
| In reply to | #70375 |
On 12/09/15 21:30, Tim Rentsch wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> 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.
>
> I'm following up here after posting my downstream response
> correcting the mistake I made. I am not repeating that but there
> are some other comments that may be useful.
>
>>> 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.)
>
> There are two problems with the idea that using the 'static'
> attribute this way is (even partly) for compile-time error
> reporting. One, because the 'static' can be there on a
> definition but not on a declaration, there is no guarantee that
> the call site knows to do the check.
Agreed. I think this is a major flaw in the way this static attribute
was introduced, and means it loses much of its potential benefits. But
compilers (and programmers) have to live with what the standards say.
Still, a compiler could warn (when the appropriate flag enabled it) for
cases that it /could/ see - and also for inconsistencies between the
definition and declaration(s).
> Two, like most conditions
> that depend on run-time values, what we're interested in cannot
> be checked in the general case.
Also agreed. But being unable to warn in the general case does not mean
a compiler cannot warn in specific cases when information is available.
For a normal array, compilers cannot in general see if you are accessing
them outside their bounds - but compilers /can/ (and recent versions of
gcc do) warn if it can see that code definitely accesses them outside
there bounds.
So being unable to identify problems in the general case is not an
excuse for not warning about bad uses of "static" function parameters.
(On the other hand, lack of time, money, volunteers, etc., is of course
a perfectly good excuse for it - especially for a relatively little-used
feature.)
> In all such cases (AFAIAA), the
> C standard relegates these to undefined behavior, leaving the
> question of any compile-time diagnostics as a QOI matter, not
> part of the official language definition. IMO this choice is
> the right decision for C (and I prefer not to consider the
> question more generally, at least as far as comp.lang.c goes).
Also agreed, at least partly. I think it would not be unreasonable to
require a diagnostic in some cases where the behaviour is clearly
undefined, but I can understand why the C standards are reluctant to do so.
>
>>> 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).
>
> I agree everything should be in sync. My preference, when
> possible, is to auto-generate the appropriate declarations based
> on the corresponding definitions. If you can get other people
> to buy into that, I find it enormously effective in terms of
> both productivity and confidence in the result.
I always insist that any functions (or variables) exported in a module
are declared with an "extern" in a matching header, that the module
imports its own header, and that any non-exported functions (or
variables) are declared "static". gcc warnings can enforce that, at
least to the level of making sure that the declarations and definitions
are compatible. I'm not so keen on automatically generating the
declarations, but I guess that works too.
>
>>> 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.
>
> Any diagnostic of this sort (ie, which is undecidable in the
> general case) comes with problems - false positives, false
> negatives, or possibly both. Also, something that may not
> have occured to you, the array bound after the 'static' might
> not be a constant. C99 has variable length arrays, which
> means that this
>
> int
> foo( int n, int v[ static n ] ){
> ...
> }
>
> is legal. Cases like this are much harder to check.
I had noticed that too, and agree that these are even harder to check.
>
> I sympathize with your desire to have diagnostics produced, where
> possible. But this is a QOI concern, not a language concern, and
> ANSI/ISO made a deliberate choice to not address QOI matters in
> the C standard. Because of that, it doesn't surprise me, or
> disappoint me, that the possibility of doing such a check for
> 'static' parameters was ignored in defining the C language.
I think the C standards could have been stricter in their definition of
static parameters, and therefore allow better diagnostics - without
necessary requiring them.
I suppose compiler developers can make warnings that enforce stronger
rules on static parameters than the standards - there is nothing to stop
a compiler warning if there are multiple declarations that don't match
the definition with regard to the size of the static parameters (as long
as it accepts legal, but silly and inconsistent code by default).
>
>>> 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 explained above why the Standard doesn't address it. As for
> compilers, of course they could, but I expect there isn't much
> call to do so, especially since there is no guarantee that the
> declarations used match the definitions.
>
>> 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".
>
> The problem is undecidable. Anything that might be done is
> a compromise that some people will be happy with and others
> will not. Unless the user community cries out for something
> I don't think anything will be done, especially since the
> problem is not just undecidable but difficult to do even
> fairly well. I believe the perception is that the ROI is
> just not very high.
>
>> As far as I can tell, the explicit undefined behaviour gives the
>> compiler a freer hand for optimisation, and that's about it.
>
> Yes, that is it, exactly 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.)
>
> And that it is hard to do well.
>
>> 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.
>
> I think you might want to re-think this position. By way of
> analogy, there's a difference between saying "I'm not going
> to drive faster than 35 miles per hour" and saying "I'm not
> going to drive faster than 35 miles per hour, and if I do
> I agree to pay you as much money as you ask for." Without
> the 'static', there may be some cases, eg based on the values
> of other parameters, that are still okay. With the 'static',
> any transgression is irredeemable. You may choose not to
> make these kinds of distinctions, but other people might,
> and IMO it is worth keeping that in mind.
It is certainly worth knowing that "static" can be used in this way.
But I am not convinced that it is useful in code. Because there is no
enforced consistency in it, and the optimisation possibilities it gives
are minimal, all it means is that if a function is declared with a
static array of size 100 then calling that function with a smaller array
is undefined behaviour even if the non-existent elements are never accessed.
I think a closer analogy would be that a non-static array parameter is
like a speed limit sign of 35 miles per hour - you can drive any car you
want on the road, but if you go about 35 miles an hour you will be
fined, arrested, or other undefined behaviour. Putting the "static" in
the array parameter means that you will be fined or arrested if your car
is capable of going over 35 miles per hour, even if you stick to the
speed limit. Now, that can have its uses - such as cycle tracks or
pavements - but it's not what you want on a typical road.
(It is difficult to make such analogies accurate. But the key point for
/me/ is that it is good to know about this use of "static", even though
I doubt if it will give any real benefit in my own code.)
>
>> [here was the part that I already addressed]
>>
>>>> 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.
>
> This statement surprised me. Do you mean you hardly ever
> pass pointer values as function parameters? Or types
> like 'char *'? Both of these cases have some potential
> benefit using 'static'.
I pass pointers around a good deal less than you might expect in more
typical C code. Most of my work is with small embedded systems, and the
type of code is quite different from what one might find on a PC. For
example, I almost never have any sort of dynamic memory in my code. And
for some of the cpus I use, any sort of pointer is quite inefficient - I
would avoid them if possible.
But I don't quite see why static array parameters would be of benefit
when I have a function using pointers. For example, if I have the function:
void displayMessage(int length, const char* msg);
I /could/ change it to:
void displayMessage(int length, const char[static length]);
And it would work the same. But I don't see any benefit here. There is
no benefit in documentation or clarity of code - the original function
would be clear already based on its name, its parameter names, the
context and surrounding comments. So unless the compiler can give me
additional help in spotting errors, it is of no advantage.
However, times change - my work involves a greater proportion of bigger
cpus than it used to, and I am seeing more pointer usage. It may be
that I will also see more use of array parameters for which "static"
could be appropriate.
>
>> 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.
>
> A pointer parameter declared like 'T x[ static 1 ]' is one that
> the compiler may assume is non-null, which may very well help
> code generation even on very low-end CPU's. (Disclaimer: I
> am certainly not an expect on optimization, but I see gcc do
> some amazing things based on such "facts", so it seems fair
> to say that the scenario is at least plausible.)
>
I can see that as a possibility.
On the other hand, I can use the gcc attribute "nonnull" on the function
to tell it that the pointer may not be null. And then the compiler not
only will optimise using that information, it will also check it (where
possible at compile-time) and issue diagnostics. Additionally, I think
the "nonnull" attribute expresses the intent a lot more directly and
clearly than using a static array parameter.
But of course the nonnull attribute is gcc-specific (possibly supported
by clang).
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-29 09:04 -0700 |
| Message-ID | <a1e6f26a-099e-444a-a4d0-3394acc5a462@googlegroups.com> |
| In reply to | #70412 |
On Sunday, September 13, 2015 at 8:49:09 AM UTC-5, David Brown wrote:
> It is certainly worth knowing that "static" can be used in this way.
> But I am not convinced that it is useful in code. Because there is no
> enforced consistency in it, and the optimisation possibilities it gives
> are minimal, all it means is that if a function is declared with a
> static array of size 100 then calling that function with a smaller array
> is undefined behaviour even if the non-existent elements are never accessed.
Consider the code:
int find_nonzero(static int foo[16384])
{
for (int i=0; i<16384; i++)
{
if (foo[i]) return 1;
}
return 0;
}
Without the static declaration, code for many platforms would be forbidden
from reading any value of "foo" without having checked whether the previous
value was non-zero (some platforms offer an architectural guarantee that
reading any address--valid or not--will have no effect besides yielding some
value, but the platforms where read-ahead is most useful generally trap on
at least some invalid reads). Adding the "static" declaration would allow
a compiler to rewrite the code as:
int anything_nonzero(static int foo[16384])
{
int a,b,c,d,*end;
end=foo+16384;
do
{
a=*foo++; b=*foo++; c=*foo++; d=*foo++;
if (a|b|c|d)
return 1;
} while(foo < end);
return 0;
}
An optimized version of the first loop version for the ARM7-TDMI would be:
LP:
LDR R1,[R0],#4
CMP R1,#1 ; Carry set if non-zero
ADDCS R2,#1 ; Arrange to hit zero at end of loop [and set carry then]
BCC LP
; At this point, R2 will be non-zero if we exited early
Three cycles for the load and branch, and one for each other instruction, so
eight cycles per integer. I don't think there's any way to improve the
code while preserving the required semantics in cases where the received
pointer is near the end of memory. The second version could be easily
optimized to:
LP:
LDRMIA R0,{R4,R5,R6,R7} ; Fetch four integers at once
IOR R7,R7,R6
IOR R7,R7,R5
IORS R7,R7,R4
BNE Done
CMP R0,R1
BCC LP
The LDRMIA would take six cycles, the branch-taken would take 3, and the
other five instructions would take one each, for a total of 14 cycles to
handle four integers, or 3.5 cycles each, a better than 50% improvement,
and that's not even the best code possible. There are actually two more
places a cycle can be cut out of the latter loop (reducing it to 3 cycles
per integer) but I wouldn't expect a compiler to find them.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-09-29 09:18 -0700 |
| Message-ID | <ln612t42sl.fsf@kst-u.example.com> |
| In reply to | #71432 |
supercat@casperkitty.com writes:
[...]
> Consider the code:
>
> int find_nonzero(static int foo[16384])
> {
[...]
> }
The correct syntax is:
int find_nonzero(int foo[static 16384])
[...]
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2015-09-29 09:57 -0700 |
| Message-ID | <9acabfe3-fbf5-4fd1-838e-ef8071815783@googlegroups.com> |
| In reply to | #71433 |
On Tuesday, September 29, 2015 at 11:18:55 AM UTC-5, Keith Thompson wrote: > The correct syntax is: > > int find_nonzero(int foo[static 16384]) Mea culpa. I think my point stands, though, which is that it gives the compiler permission to access elements of `foo` in advance of discovering that their values are needed. Some would argue that such a thing should be better notated by adding a reference to "foo[16383]" early in the code, and others (myself included) might suggest that a new keyword starting with double-underscores might have been a better choice [so that compilers which don't understand the notation could be made to ignore it by simply adding e.g. "#define __stdc_readahead"] but having a means of suggesting that a compiler should feel free to read data ahead of time, but should feel no imperative to do so unless it's useful, would seem like a good concept [IMHO, things that look like executable code should have a purpose if executed; I dislike the idea of writing things that look like executable code for the purpose of affecting the compiler's treatment of other code while hoping that the code I wrote for that purpose doesn't actually end up in the executable].
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2015-08-29 14:18 -0700 |
| Message-ID | <39cec144-8114-4041-8cd5-f4982dabb69a@googlegroups.com> |
| In reply to | #68656 |
W dniu sobota, 29 sierpnia 2015 22:53:27 UTC+2 użytkownik David Kleinecke napisał: > 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 storeage class 28, 80, 191 then i would have to be sure that this "static storage class" dont just mean 'module level variables that are of internal visibility' but the second meaning... becouse both might be maybe understood storage class does it for sure mean this function level non-stack storage there? could you look up to this pages maybe to see?
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2015-09-01 01:36 -0700 |
| Message-ID | <085cf084-bd17-4029-b1d4-794916685640@googlegroups.com> |
| In reply to | #68660 |
W dniu sobota, 29 sierpnia 2015 23:18:59 UTC+2 użytkownik fir napisał: > could you look up to this pages maybe > to see? to be honest both those parts of answers are unclear 1) in this algol (65? date here needed) this static is same static i mean here (like global living time but function body scope only) 2) in this c-73 is this static i mean present for SURE? (quotations form index with word ststic doeas say to much as static is duplicated meaning in c)
[toc] | [prev] | [next] | [standalone]
Page 2 of 5 — ← Prev page 1 [2] 3 4 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web