Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #29889 > unrolled thread
| Started by | m.labanowicz@gmail.com |
|---|---|
| First post | 2013-01-09 07:26 -0800 |
| Last post | 2013-01-11 08:32 -0500 |
| Articles | 20 on this page of 48 — 8 participants |
Back to article view | Back to comp.lang.c
[MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-09 07:26 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? James Kuyper <jameskuyper@verizon.net> - 2013-01-09 11:30 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-09 11:58 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Robert Wessel <robertwessel2@yahoo.com> - 2013-01-09 12:27 -0600
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-09 11:22 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-09 14:39 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-10 02:40 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-10 08:31 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-10 08:49 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-10 06:48 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-10 10:33 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-11 08:19 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-11 12:46 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-11 14:04 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-11 22:42 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-12 01:44 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-11 19:30 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-11 20:11 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-12 01:17 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-11 20:46 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-12 03:14 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-12 14:17 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-12 18:02 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-12 15:13 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-13 16:36 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-13 15:39 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-13 19:17 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-13 16:57 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-13 20:50 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-13 19:08 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-14 00:00 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-14 21:21 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-14 17:50 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-14 01:23 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-13 21:04 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-13 19:13 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-14 21:37 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-11 18:28 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Keith Thompson <kst-u@mib.org> - 2013-01-11 18:40 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-12 04:30 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-10 14:37 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-10 06:51 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-10 07:41 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-10 16:55 +0000
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? Shao Miller <sha0.miller@gmail.com> - 2013-01-10 17:41 -0500
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-11 03:03 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? m.labanowicz@gmail.com - 2013-01-11 04:14 -0800
Re: [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ? James Kuyper <jameskuyper@verizon.net> - 2013-01-11 08:32 -0500
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-12 03:14 +0000 |
| Message-ID | <kcqkea$jui$1@speranza.aioe.org> |
| In reply to | #29988 |
Shao Miller <sha0.miller@gmail.com> wrote: (snip, I wrote) >> As long as it isn't used to index any actual array, I agree. >>> But that's not so. A compiler can plainly see an integer object being >>> compared with the bounds of an array, as does the code I was >>> criticizing. For example: >>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10) >>> If the count of 'arr' is 4, this alone is sufficient cause to tell the >>> programmer to have their head checked, with no pointers in sight. >> (And I presume referencing arr[i] inside the loop.) > No, that was the point. There is no 'arr[i]' in the loop and yet the > compiler (or run-time support, perhaps) can still see that something > doesn't seem quite right about this. Why is 'i' being incremented by 10 > and then compared against the length of 'arr'? Seems fishy. Doesn't seem fishy at all. Reasonably often I want to go through an array and look at only even elements, or even every 10th element, but ignore any fraction left at the end. Certainly there should be something inside the loop, otherwise i=(sizeof(arr)/sizeof(*arr)+9)/10*10; >> Yes the compiler can plainly see that i indexes the array, and >> also that it can never have a value inside the loop that will >> exceed the array bounds. >> A compiler that does bounds checking might not check references >> to arr[i] inside the loop, as it is known to be in bounds. >> (Unless i is otherwise changed inside the loop.) > Well my point here was that the loop body didn't make a difference. Might as well put a warning on all for loops, then. >>>> That is, unless you actually use the integer value as an index into >>>> a particular array. In that case, exactly the same rules apply as >>>> for pointers, because the indexing operation is defined in terms >>>> of pointer arithmetic. (snip) > Sorry; wasn't talking about the Standard and its rationale, but about my > recollection of the rationale for the diagnostic which could be emitted > as a sanity-check for a conforming program. And it makes sense, to me, > as something that can benefit the programmer (or at least, _other_ > programmers reading the code; heh!). (snip) > Right. :) It's not that there's an actual problem with the operation, > it's a diagnostic for the senselessness of the code. But it isn't sensless. I suppose there is some small probabiity that it isn't what was meant, but pretty small. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-12 14:17 -0800 |
| Message-ID | <lnobguhwql.fsf@nuthaus.mib.org> |
| In reply to | #29988 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/11/2013 20:17, glen herrmannsfeldt wrote:
>> Shao Miller <sha0.miller@gmail.com> wrote:
[...]
>>> But that's not so. A compiler can plainly see an integer object being
>>> compared with the bounds of an array, as does the code I was
>>> criticizing. For example:
>>
>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>>
>>> If the count of 'arr' is 4, this alone is sufficient cause to tell the
>>> programmer to have their head checked, with no pointers in sight.
>>
>> (And I presume referencing arr[i] inside the loop.)
>
> No, that was the point. There is no 'arr[i]' in the loop and yet the
> compiler (or run-time support, perhaps) can still see that something
> doesn't seem quite right about this. Why is 'i' being incremented by
> 10 and then compared against the length of 'arr'? Seems fishy.
The point of the check is precisely to prevent any invalid access to the
array. Warning about it would make as much sense as this:
int x, y, z;
/* code to set x, y, and z */
if (y == 0) {
z = 0;
}
else {
z = x / y;
}
triggering a warning about a possible division by zero.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-12 18:02 -0500 |
| Message-ID | <kcsq2q$8je$1@dont-email.me> |
| In reply to | #30035 |
On 1/12/2013 17:17, Keith Thompson wrote: > > The point of the check is precisely to prevent any invalid access to the > array. ... > Absolutely agreed. What I meant to suggest was that the particular diagnostic that I recalled could be emitted regardless of the loop body. I could be misremembering. Please see elsethread for recollection details, for what they're worth. :) Once again, here's a piece from the FORTIFY_SOURCE patch: "With -D_FORTIFY_SOURCE=2 some more checking is added, but some conforming programs might fail." -- Jakub Jelinek A false positive can still be useful (a bonus) in order to draw attention to weird code for closer scrutiny, but to break translation is a problem, in my opinion. I respect your difference of opinion, if indeed your opinion differs. -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-12 15:13 -0800 |
| Message-ID | <lnk3rihu51.fsf@nuthaus.mib.org> |
| In reply to | #30039 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/12/2013 17:17, Keith Thompson wrote:
>>
>> The point of the check is precisely to prevent any invalid access to the
>> array. ...
>>
>
> Absolutely agreed. What I meant to suggest was that the particular
> diagnostic that I recalled could be emitted regardless of the loop body.
> I could be misremembering. Please see elsethread for recollection
> details, for what they're worth. :)
>
> Once again, here's a piece from the FORTIFY_SOURCE patch:
>
> "With -D_FORTIFY_SOURCE=2 some more checking is added, but some
> conforming programs might fail." -- Jakub Jelinek
>
> A false positive can still be useful (a bonus) in order to draw
> attention to weird code for closer scrutiny, but to break translation is
> a problem, in my opinion. I respect your difference of opinion, if
> indeed your opinion differs.
I still fail to understand why you think the code in question is weird
or, as you wrote, "is sufficient cause to tell the programmer to have
their head checked".
How would you re-write
for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
to make it less weird?
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-13 16:36 -0500 |
| Message-ID | <kcv9cb$a2g$1@dont-email.me> |
| In reply to | #30041 |
On 1/12/2013 18:13, Keith Thompson wrote: > Shao Miller <sha0.miller@gmail.com> writes: >> On 1/12/2013 17:17, Keith Thompson wrote: >>> >>> The point of the check is precisely to prevent any invalid access to the >>> array. ... >>> >> >> Absolutely agreed. What I meant to suggest was that the particular >> diagnostic that I recalled could be emitted regardless of the loop body. >> I could be misremembering. Please see elsethread for recollection >> details, for what they're worth. :) >> >> Once again, here's a piece from the FORTIFY_SOURCE patch: >> >> "With -D_FORTIFY_SOURCE=2 some more checking is added, but some >> conforming programs might fail." -- Jakub Jelinek >> >> A false positive can still be useful (a bonus) in order to draw >> attention to weird code for closer scrutiny, but to break translation is >> a problem, in my opinion. I respect your difference of opinion, if >> indeed your opinion differs. > > I still fail to understand why you think the code in question is weird > or, as you wrote, "is sufficient cause to tell the programmer to have > their head checked". > > How would you re-write > > for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10) > > to make it less weird? > On its own, it looks like it's about to work with every 10th element of 'arr'. Since all elements should be initialized, I'd suggest dealing with the "every tenth" case in the same place (loop) as the rest of the elements are dealt with. Sometimes, I agree, it doesn't make sense to do so. But if it does, then noticing this code and thinking twice about it doesn't seem to hurt. The loop body for this could very well initialize ten elements at a time, but I'd probably advance 'i' by 1 instead of by 10, and use the '% 10' operator in the loop's body, if need be. From looking at just this loop, I'd think that some bodies would be rather contrived, especially because of the 'sizeof' count computation instead of 'n', or some such. -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-13 15:39 -0800 |
| Message-ID | <lnfw24d55f.fsf@nuthaus.mib.org> |
| In reply to | #30080 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/12/2013 18:13, Keith Thompson wrote:
[...]
>> I still fail to understand why you think the code in question is weird
>> or, as you wrote, "is sufficient cause to tell the programmer to have
>> their head checked".
>>
>> How would you re-write
>>
>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>>
>> to make it less weird?
>>
>
> On its own, it looks like it's about to work with every 10th element of
> 'arr'. Since all elements should be initialized, I'd suggest dealing
> with the "every tenth" case in the same place (loop) as the rest of the
> elements are dealt with. Sometimes, I agree, it doesn't make sense to
> do so. But if it does, then noticing this code and thinking twice about
> it doesn't seem to hurt.
Let's assume that we really want to deal only with every 10th element
rather than second-guessing the intent.
> The loop body for this could very well initialize ten elements at a
> time, but I'd probably advance 'i' by 1 instead of by 10, and use the '%
> 10' operator in the loop's body, if need be. From looking at just this
> loop, I'd think that some bodies would be rather contrived, especially
> because of the 'sizeof' count computation instead of 'n', or some such.
So you'd rather iterate over every element of the array, and then
test i%10 to decide whether to process the current one?
for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
if (i % 10 == 0) {
/* ... */
}
}
I find that more verbose, less clear, and almost certainly less
efficient (unless the compiler is clever enough to transform it
into the first form). All to solve a problem that is not a problem
at all.
If there's some concern about i overflowing the upper limit of its
type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
I want to look at and use that to control the loop. But I see no
point in doing so just to avoid letting i exceed the upper bound
of the array, when the code explicitly avoids accessing anything
outside the array bounds.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-13 19:17 -0500 |
| Message-ID | <kcviqf$344$1@dont-email.me> |
| In reply to | #30087 |
On 1/13/2013 18:39, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/12/2013 18:13, Keith Thompson wrote:
> [...]
>>> I still fail to understand why you think the code in question is weird
>>> or, as you wrote, "is sufficient cause to tell the programmer to have
>>> their head checked".
>>>
>>> How would you re-write
>>>
>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>>>
>>> to make it less weird?
>>>
>>
>> On its own, it looks like it's about to work with every 10th element of
>> 'arr'. Since all elements should be initialized, I'd suggest dealing
>> with the "every tenth" case in the same place (loop) as the rest of the
>> elements are dealt with. Sometimes, I agree, it doesn't make sense to
>> do so. But if it does, then noticing this code and thinking twice about
>> it doesn't seem to hurt.
>
> Let's assume that we really want to deal only with every 10th element
> rather than second-guessing the intent.
>
That is just what I've been trying to suggest: The diagnostic can be
considered useful for second-guessing the intention. I cannot argue
that if I begin by agreeing that it's false. :)
>> The loop body for this could very well initialize ten elements at a
>> time, but I'd probably advance 'i' by 1 instead of by 10, and use the '%
>> 10' operator in the loop's body, if need be. From looking at just this
>> loop, I'd think that some bodies would be rather contrived, especially
>> because of the 'sizeof' count computation instead of 'n', or some such.
>
> So you'd rather iterate over every element of the array, and then
> test i%10 to decide whether to process the current one?
>
> for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
> if (i % 10 == 0) {
> /* ... */
> }
> }
>
> I find that more verbose, less clear, and almost certainly less
> efficient (unless the compiler is clever enough to transform it
> into the first form). All to solve a problem that is not a problem
> at all.
>
> If there's some concern about i overflowing the upper limit of its
> type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
> I want to look at and use that to control the loop. But I see no
> point in doing so just to avoid letting i exceed the upper bound
> of the array, when the code explicitly avoids accessing anything
> outside the array bounds.
>
No, I was talking about if the loop was for initialization. In such a
case, I'd initialize every element (advancing by 1), but if something
special was needed for every tenth, I could determine that with your 'if'.
For just _working_ with an already-initialized array, I'd probably use
precisely this loop (though I might possibly be more inclined to put it
in a function and pass the count). BUT, as was snipped, if the count of
'arr' is 4, then the programmer _really_ ought to have their head
checked. :)
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-13 16:57 -0800 |
| Message-ID | <ln7gngd1jz.fsf@nuthaus.mib.org> |
| In reply to | #30090 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/13/2013 18:39, Keith Thompson wrote:
[...]
>> So you'd rather iterate over every element of the array, and then
>> test i%10 to decide whether to process the current one?
>>
>> for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
>> if (i % 10 == 0) {
>> /* ... */
>> }
>> }
>>
>> I find that more verbose, less clear, and almost certainly less
>> efficient (unless the compiler is clever enough to transform it
>> into the first form). All to solve a problem that is not a problem
>> at all.
>>
>> If there's some concern about i overflowing the upper limit of its
>> type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
>> I want to look at and use that to control the loop. But I see no
>> point in doing so just to avoid letting i exceed the upper bound
>> of the array, when the code explicitly avoids accessing anything
>> outside the array bounds.
>
> No, I was talking about if the loop was for initialization. In such a
> case, I'd initialize every element (advancing by 1), but if something
> special was needed for every tenth, I could determine that with your 'if'.
Who says the loop is for initialization? It might not even be writing
to the array.
> For just _working_ with an already-initialized array, I'd probably use
> precisely this loop (though I might possibly be more inclined to put it
> in a function and pass the count). BUT, as was snipped, if the count of
> 'arr' is 4, then the programmer _really_ ought to have their head
> checked. :)
Absurd.
A function that, for whatever reason, needs to access every 10th
(or every Nth) element, can perfectly sensibly work on an array of
any size. If the array has 10 or fewer elements, the function just
accesses element 0. I see no reason to treat that as a special case.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-13 20:50 -0500 |
| Message-ID | <kcvo9s$shm$1@dont-email.me> |
| In reply to | #30092 |
On 1/13/2013 19:57, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/13/2013 18:39, Keith Thompson wrote:
> [...]
>>> So you'd rather iterate over every element of the array, and then
>>> test i%10 to decide whether to process the current one?
>>>
>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
>>> if (i % 10 == 0) {
>>> /* ... */
>>> }
>>> }
>>>
>>> I find that more verbose, less clear, and almost certainly less
>>> efficient (unless the compiler is clever enough to transform it
>>> into the first form). All to solve a problem that is not a problem
>>> at all.
>>>
>>> If there's some concern about i overflowing the upper limit of its
>>> type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
>>> I want to look at and use that to control the loop. But I see no
>>> point in doing so just to avoid letting i exceed the upper bound
>>> of the array, when the code explicitly avoids accessing anything
>>> outside the array bounds.
>>
>> No, I was talking about if the loop was for initialization. In such a
>> case, I'd initialize every element (advancing by 1), but if something
>> special was needed for every tenth, I could determine that with your 'if'.
>
> Who says the loop is for initialization? It might not even be writing
> to the array.
>
I did. "The loop body for this could very well initialize ten elements
at a time, but I'd probably advance 'i' by 1 instead of by 10, and use
the '% 10' operator in the loop's body, if need be." (If you'll forgive
the 10 with "operator") I'm saying "if, then", not making a claim about
the loop's purpose.
>> For just _working_ with an already-initialized array, I'd probably use
>> precisely this loop (though I might possibly be more inclined to put it
>> in a function and pass the count). BUT, as was snipped, if the count of
>> 'arr' is 4, then the programmer _really_ ought to have their head
>> checked. :)
>
> Absurd.
>
> A function that, for whatever reason, needs to access every 10th
> (or every Nth) element, can perfectly sensibly work on an array of
> any size. If the array has 10 or fewer elements, the function just
> accesses element 0. I see no reason to treat that as a special case.
>
If you are talking about:
void some_func1(void) {
int arr[4];
int i;
for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
/* Anything */
}
then I'd certainly say it's silly! We can see right away that the
advancement of 'i' is silly! Consider what kind of code review you'd
offer someone about this.
If you are talking about:
void some_func1(int * arr, size_t n) {
int i;
for (i = 0; i < n; i += 10)
/* Anything */
}
then I'd certainly say it's not silly at all!
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-13 19:08 -0800 |
| Message-ID | <ln38y4cvg9.fsf@nuthaus.mib.org> |
| In reply to | #30099 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/13/2013 19:57, Keith Thompson wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>> On 1/13/2013 18:39, Keith Thompson wrote:
>> [...]
>>>> So you'd rather iterate over every element of the array, and then
>>>> test i%10 to decide whether to process the current one?
>>>>
>>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
>>>> if (i % 10 == 0) {
>>>> /* ... */
>>>> }
>>>> }
>>>>
>>>> I find that more verbose, less clear, and almost certainly less
>>>> efficient (unless the compiler is clever enough to transform it
>>>> into the first form). All to solve a problem that is not a problem
>>>> at all.
>>>>
>>>> If there's some concern about i overflowing the upper limit of its
>>>> type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
>>>> I want to look at and use that to control the loop. But I see no
>>>> point in doing so just to avoid letting i exceed the upper bound
>>>> of the array, when the code explicitly avoids accessing anything
>>>> outside the array bounds.
>>>
>>> No, I was talking about if the loop was for initialization. In such a
>>> case, I'd initialize every element (advancing by 1), but if something
>>> special was needed for every tenth, I could determine that with your 'if'.
>>
>> Who says the loop is for initialization? It might not even be writing
>> to the array.
>
> I did. "The loop body for this could very well initialize ten elements
> at a time, but I'd probably advance 'i' by 1 instead of by 10, and use
> the '% 10' operator in the loop's body, if need be." (If you'll forgive
> the 10 with "operator") I'm saying "if, then", not making a claim about
> the loop's purpose.
My point is that you were making an unwarranted assumption. The example
illustrates iterating over every 10 (or N) elements of an array.
>>> For just _working_ with an already-initialized array, I'd probably use
>>> precisely this loop (though I might possibly be more inclined to put it
>>> in a function and pass the count). BUT, as was snipped, if the count of
>>> 'arr' is 4, then the programmer _really_ ought to have their head
>>> checked. :)
>>
>> Absurd.
>>
>> A function that, for whatever reason, needs to access every 10th
>> (or every Nth) element, can perfectly sensibly work on an array of
>> any size. If the array has 10 or fewer elements, the function just
>> accesses element 0. I see no reason to treat that as a special case.
>
> If you are talking about:
>
> void some_func1(void) {
> int arr[4];
> int i;
>
> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
> /* Anything */
> }
>
> then I'd certainly say it's silly! We can see right away that the
> advancement of 'i' is silly! Consider what kind of code review you'd
> offer someone about this.
It's common to use "magic numbers" (4 and 10 in this case) for code
snippets meant to illustrate a point. In real life, clearly the
value would be either a named constant or a value computed at run
time (in the latter case allocating the array is more complicated).
Is that the trivial point you've been trying to make all this time?
Ok, suppose we replace 4 by ARRAY_SIZE, a macro whose value
is determined by some build-time configuration process. Maybe
ARRAY_SIZE happens to be 4.
Or suppose it's a constant value 95, which will result in the final
value of i being 100, past the end of the array.
> If you are talking about:
>
> void some_func1(int * arr, size_t n) {
> int i;
>
> for (i = 0; i < n; i += 10)
> /* Anything */
> }
>
> then I'd certainly say it's not silly at all!
What I *thought* you were objecting to is having i end up with a
value past the last valid index of arr, to the point where you'd
want a compiler to warn you about it. Both code snippets quoted
above have the same non-problem.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-14 00:00 -0500 |
| Message-ID | <kd03dl$cl7$1@dont-email.me> |
| In reply to | #30101 |
On 1/13/2013 22:08, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> On 1/13/2013 19:57, Keith Thompson wrote:
>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>> On 1/13/2013 18:39, Keith Thompson wrote:
>>> [...]
>>>>> So you'd rather iterate over every element of the array, and then
>>>>> test i%10 to decide whether to process the current one?
>>>>>
>>>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i ++) {
>>>>> if (i % 10 == 0) {
>>>>> /* ... */
>>>>> }
>>>>> }
>>>>>
>>>>> I find that more verbose, less clear, and almost certainly less
>>>>> efficient (unless the compiler is clever enough to transform it
>>>>> into the first form). All to solve a problem that is not a problem
>>>>> at all.
>>>>>
>>>>> If there's some concern about i overflowing the upper limit of its
>>>>> type (INT_MAX or SIZE_MAX), I'd probably precompute the last index
>>>>> I want to look at and use that to control the loop. But I see no
>>>>> point in doing so just to avoid letting i exceed the upper bound
>>>>> of the array, when the code explicitly avoids accessing anything
>>>>> outside the array bounds.
>>>>
>>>> No, I was talking about if the loop was for initialization. In such a
>>>> case, I'd initialize every element (advancing by 1), but if something
>>>> special was needed for every tenth, I could determine that with your 'if'.
>>>
>>> Who says the loop is for initialization? It might not even be writing
>>> to the array.
>>
>> I did. "The loop body for this could very well initialize ten elements
>> at a time, but I'd probably advance 'i' by 1 instead of by 10, and use
>> the '% 10' operator in the loop's body, if need be." (If you'll forgive
>> the 10 with "operator") I'm saying "if, then", not making a claim about
>> the loop's purpose.
>
> My point is that you were making an unwarranted assumption. The example
> illustrates iterating over every 10 (or N) elements of an array.
>
For the second time, I'm saying "if, then". :) I'm handling a
possibility with a response.
Why didn't you suggest that the 'for' loop has nothing to do with
iterating over the array? Maybe the programmer simply wants to load a
value into 'i' and knows something about the length of the array that
can help them to get the right value in there, when combined with the
'for' loop's expression-3?
>>>> For just _working_ with an already-initialized array, I'd probably use
>>>> precisely this loop (though I might possibly be more inclined to put it
>>>> in a function and pass the count). BUT, as was snipped, if the count of
>>>> 'arr' is 4, then the programmer _really_ ought to have their head
>>>> checked. :)
>>>
>>> Absurd.
>>>
>>> A function that, for whatever reason, needs to access every 10th
>>> (or every Nth) element, can perfectly sensibly work on an array of
>>> any size. If the array has 10 or fewer elements, the function just
>>> accesses element 0. I see no reason to treat that as a special case.
>>
>> If you are talking about:
>>
>> void some_func1(void) {
>> int arr[4];
>> int i;
>>
>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>> /* Anything */
>> }
>>
>> then I'd certainly say it's silly! We can see right away that the
>> advancement of 'i' is silly! Consider what kind of code review you'd
>> offer someone about this.
>
> It's common to use "magic numbers" (4 and 10 in this case) for code
> snippets meant to illustrate a point. In real life, clearly the
> value would be either a named constant or a value computed at run
> time (in the latter case allocating the array is more complicated).
>
> Is that the trivial point you've been trying to make all this time?
>
> Ok, suppose we replace 4 by ARRAY_SIZE, a macro whose value
> is determined by some build-time configuration process. Maybe
> ARRAY_SIZE happens to be 4.
>
> Or suppose it's a constant value 95, which will result in the final
> value of i being 100, past the end of the array.
>
Yes. Using 'ARRAY_SIZE' with that loop strikes me as waiting for an
accident.
Some day, someone else could look at the loop and think, "Oh, it seems
that this array is always going to be a multiple of ten, in length." I
don't think a quick glance would make that an unfair assumption.
Also bad: Someone _worries_ about it being out-of-bounds and wastes time
looking at it, because it's suspicious and they recently had a crash.
>> If you are talking about:
>>
>> void some_func1(int * arr, size_t n) {
>> int i;
>>
>> for (i = 0; i < n; i += 10)
>> /* Anything */
>> }
>>
>> then I'd certainly say it's not silly at all!
>
> What I *thought* you were objecting to is having i end up with a
> value past the last valid index of arr, to the point where you'd
> want a compiler to warn you about it. Both code snippets quoted
> above have the same non-problem.
>
There is another C-devoted forum that I spend some time in. I see a lot
of code flow by. When I see weird loops, I usually mention them to the
programmer. Some day, maybe a compiler could take care of that bit, as
a quick pass. :)
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-14 21:21 +0000 |
| Message-ID | <kd1sta$9jg$1@speranza.aioe.org> |
| In reply to | #30099 |
Shao Miller <sha0.miller@gmail.com> wrote:
(snip, someone wrote)
>> Who says the loop is for initialization? It might not even be writing
>> to the array.
> I did. "The loop body for this could very well initialize ten elements
> at a time, but I'd probably advance 'i' by 1 instead of by 10, and use
> the '% 10' operator in the loop's body, if need be." (If you'll forgive
> the 10 with "operator") I'm saying "if, then", not making a claim about
> the loop's purpose.
(snip)
> If you are talking about:
> void some_func1(void) {
> int arr[4];
> int i;
>
> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
> /* Anything */
> }
> then I'd certainly say it's silly! We can see right away that the
> advancement of 'i' is silly! Consider what kind of code review you'd
> offer someone about this.
OK, how about:
#define N 4
void some_func1(void) {
int arr[N];
int i;
for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
/* Anything */
}
Depending on how the preprocessor is implemented, the compiler still
sees 4, but the N could change later.
-- glen
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-14 17:50 -0500 |
| Message-ID | <kd2234$h98$1@dont-email.me> |
| In reply to | #30137 |
On 1/14/2013 16:21, glen herrmannsfeldt wrote:
> Shao Miller <sha0.miller@gmail.com> wrote:
>
> (snip, someone wrote)
>>> Who says the loop is for initialization? It might not even be writing
>>> to the array.
>
>> I did. "The loop body for this could very well initialize ten elements
>> at a time, but I'd probably advance 'i' by 1 instead of by 10, and use
>> the '% 10' operator in the loop's body, if need be." (If you'll forgive
>> the 10 with "operator") I'm saying "if, then", not making a claim about
>> the loop's purpose.
>
> (snip)
>
>> If you are talking about:
>
>> void some_func1(void) {
>> int arr[4];
>> int i;
>>
>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>> /* Anything */
>> }
>
>> then I'd certainly say it's silly! We can see right away that the
>> advancement of 'i' is silly! Consider what kind of code review you'd
>> offer someone about this.
>
> OK, how about:
>
> #define N 4
> void some_func1(void) {
> int arr[N];
> int i;
>
> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
> /* Anything */
> }
>
> Depending on how the preprocessor is implemented, the compiler still
> sees 4, but the N could change later.
>
I'm not too sure how to respond to this. :)
Yes, if I read this code, I would ask the programmer why they were
incrementing 'i' by 10, but comparing with 4 in a loop.
Yes, if I recall my experience correctly, GCC with some particular
translation options once emitted an "index out-of-bounds"-style warning
when it looked like the index might index beyond the bounds of the array.
No, I don't think there's anything undefined about the example, other
than the missing statement which has been obviously replaced with a
comment for demonstration purposes.
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-14 01:23 +0000 |
| Message-ID | <kcvmmr$4it$1@speranza.aioe.org> |
| In reply to | #30090 |
Shao Miller <sha0.miller@gmail.com> wrote: (snip) >>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10) (snip) >> Let's assume that we really want to deal only with every 10th element >> rather than second-guessing the intent. > That is just what I've been trying to suggest: The diagnostic can be > considered useful for second-guessing the intention. I cannot argue > that if I begin by agreeing that it's false. :) Yes, but so can a few million other things. It doesn't help much to put on each statement: "Warning: this statement could be wrong" If you find the statement: i += 3; You could have the warning: "Are you sure you meant 3, and not 4?" and once in about 1e12 times you might be right. Warnings have a cost, if nothing else than in the time the programmer has to read them and ignore them. But even more, too many warnings will make it more likely to miss the ones that are actually important. The programmer will just give up and turn them off. So, really really think about how useful a warning will be before suggesting that it should be added. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-13 21:04 -0500 |
| Message-ID | <kcvp2l$fe$1@dont-email.me> |
| In reply to | #30095 |
On 1/13/2013 20:23, glen herrmannsfeldt wrote: > Shao Miller <sha0.miller@gmail.com> wrote: > > (snip) >>>>> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10) > > (snip) > >>> Let's assume that we really want to deal only with every 10th element >>> rather than second-guessing the intent. > >> That is just what I've been trying to suggest: The diagnostic can be >> considered useful for second-guessing the intention. I cannot argue >> that if I begin by agreeing that it's false. :) > > Yes, but so can a few million other things. > > It doesn't help much to put on each statement: > > "Warning: this statement could be wrong" > > If you find the statement: > > i += 3; > > You could have the warning: "Are you sure you meant 3, and not 4?" > > and once in about 1e12 times you might be right. > > Warnings have a cost, if nothing else than in the time the programmer > has to read them and ignore them. But even more, too many warnings will > make it more likely to miss the ones that are actually important. > The programmer will just give up and turn them off. > > So, really really think about how useful a warning will be before > suggesting that it should be added. > Sure. Let me try to provide some of the missing context: Once upon a time, I saw a warning about a 'for' loop. It turned out that there was nothing wrong with the 'for' loop, behaviour-wise, but the loop could've been reworked so as to avoid the warning, and to look more sensible besides that. We were using -Werror, so the warning actually stopped the build process, which was undesirable. It was especially undesirable since it was a false positive for out-of-bounds. It was, however, still useful for drawing attention to the weird loop, and for understanding that behind the scenes, the array index and a pointer arithmetic alternative happened to be translating the same way. It turns out that we didn't desire such false positives, so we removed this ambitious form of warning and left the loop as-is. So I wouldn't be surprised if mudflap did the same thing, even though the program is fine. -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-13 19:13 -0800 |
| Message-ID | <lny5fwbgov.fsf@nuthaus.mib.org> |
| In reply to | #30100 |
Shao Miller <sha0.miller@gmail.com> writes:
[...]
> Once upon a time, I saw a warning about a 'for' loop. It turned out
> that there was nothing wrong with the 'for' loop, behaviour-wise, but
> the loop could've been reworked so as to avoid the warning, and to look
> more sensible besides that. We were using -Werror, so the warning
> actually stopped the build process, which was undesirable. It was
> especially undesirable since it was a false positive for out-of-bounds.
> It was, however, still useful for drawing attention to the weird loop,
> and for understanding that behind the scenes, the array index and a
> pointer arithmetic alternative happened to be translating the same way.
I have yet to see, in this thread, an example of a loop that I
would consider "weird" in the way you describe. I wouldn't be
at all surprised to see an example that meets your description,
and I'm mildly curious what the perceived problem was.
> It turns out that we didn't desire such false positives, so we removed
> this ambitious form of warning and left the loop as-is.
>
> So I wouldn't be surprised if mudflap did the same thing, even though
> the program is fine.
I'd be very surprised if mudflap complained about the specific case
you've been talking about, an integer that exceeds the bounds of an
array with code that guarantees it won't be used to index outside the
array.
--
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 | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-14 21:37 +0000 |
| Message-ID | <kd1tq4$bq7$1@speranza.aioe.org> |
| In reply to | #30100 |
Shao Miller <sha0.miller@gmail.com> wrote: (snip, I wrote) >> Warnings have a cost, if nothing else than in the time the programmer >> has to read them and ignore them. But even more, too many warnings will >> make it more likely to miss the ones that are actually important. >> The programmer will just give up and turn them off. >> So, really really think about how useful a warning will be before >> suggesting that it should be added. > Sure. Let me try to provide some of the missing context: > Once upon a time, I saw a warning about a 'for' loop. It turned out > that there was nothing wrong with the 'for' loop, behaviour-wise, but > the loop could've been reworked so as to avoid the warning, and to look > more sensible besides that. We were using -Werror, so the warning > actually stopped the build process, which was undesirable. It was > especially undesirable since it was a false positive for out-of-bounds. > It was, however, still useful for drawing attention to the weird loop, > and for understanding that behind the scenes, the array index and a > pointer arithmetic alternative happened to be translating the same way. Some years ago, I noticed that when I went to the library to look up a journal article, I would find another interesting, but unrelated, article at the same time. It is certainly possible that if you issue enough warnings that some fraction of them will be near actual errors that the compiler didn't detect. Depending on your defintion of "near", you might even make a statistical case for the warnings. Consider a compiler that, on every expression evaluation gives a warning: "Possible overflow in this expression." Every once in a while, it might help you notice that you had missed considering the possible overflow in that expression, but way more often it just makes you mad. > It turns out that we didn't desire such false positives, so we > removed this ambitious form of warning and left the loop as-is. If the warning can have false positives (and if it can't, then it should probably be an error) you have to consider the cost of those false positives. Note that the same is true for medical tests, and there is much discussion on the value of such tests, and when they should and should not be done. Balance the cost, including the cost of false positives, against the benefit, and decide what is worth doing. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-11 18:28 -0800 |
| Message-ID | <lnpq1bjfsz.fsf@nuthaus.mib.org> |
| In reply to | #29982 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
[...]
> The standard prohibits pointers from pointing more than one past the
> end of an array, not to aid bounds checking but to allow for hardware
> that might have restrictions on pointers. (Well, that it my
> understanding of the reason.)
[...]
In fact, the "prohibition" doesn't *aid* bounds checking at all; rather,
since the behavior is undefined, it permits implementations to check
bounds or not as they see fit.
--
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 | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-11 18:40 -0800 |
| Message-ID | <lnlibzjf8e.fsf@nuthaus.mib.org> |
| In reply to | #29978 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 1/11/2013 17:04, Keith Thompson wrote:
[...]
>> It's permitted (in all versions of the language) for a object
>> of an integer type to have any value in the range of that type.
>> That has nothing at all to do with arrays; there's no association
>> (that a compiler can detect) between a given integer value and
>> indices into some array object.
>
> But that's not so. A compiler can plainly see an integer object being
> compared with the bounds of an array, as does the code I was
> criticizing. For example:
>
> for (i = 0; i < sizeof arr / sizeof arr[0]; i += 10)
>
> If the count of 'arr' is 4, this alone is sufficient cause to tell the
> programmer to have their head checked, with no pointers in sight.
Hardly. If I want to access every 10th element of an array, starting
from element 0, the above is a perfectly good way to do that. If the
array has 10 or fewer elements, it will access only element 0. If it
has 23 elements, it will access elements 0, 10, and 20, and then leave i
with the value 30.
It *doesn't matter* that the value of i goes past the last valid index
of the array, as long as I don't use that value to index the array. The
upper bound for i is INT_MAX.
(This is a significant difference between accessing arrays with integer
indices vs. using pointers, and one that hadn't occurred to be before.
It probably doesn't show up very often, we don't usually skip through
arrays like this.)
>> That is, unless you actually use the integer value as an index into
>> a particular array. In that case, exactly the same rules apply as
>> for pointers, because the indexing operation is defined in terms
>> of pointer arithmetic.
>>
>> Concretely:
>>
>> int arr[10] = { 0 };
>> int i;
>> for (i = 0; i < 10; i += 3) {
>> arr[i] = 42;
>> }
>>
>> In successive iterations of the loop, i takes on the values 0, 3,
>> 6, and 9. *After* the loop, i==12, which is a perfectly valid value
>> for an object of type int. Evaluating `arr[i]` after the loop would
>> have undefined behavior, but the program doesn't do that so there's
>> no problem. There could be problems if i iterates past INT_MAX,
>> but it doesn't do that either.
>
> This example is a good one, and rings a bell as being along the lines
> of the bonus diagnostic I mentioned.
I'm tempted to suggest that you've misspelled "bogus". 8-)}
> If I recall correctly, the idea is that whether or not one is using an
> integer index or a pointer itself for iteration is hardly any
> different to the compiler, so noting that an index goes "out of
> bounds" is just as easy as noting that a pointer goes out of bounds,
> so it's pretty straightforward to provide a bonus diagnostic, even
> though the program might not suffer from undefined behaviour.
I would not want a compiler to produce a diagnostic like this.
[...]
> Not that I know of. :) It's just helpful, because it's usually
> right... The loop is usually clearer if it's reworked to avoid the
> diagnostic.
I could rework that loop to avoid letting i exceed 10, but I believe the
result would be substantially less clear:
#define LEN 10
int arr[LEN] = { 0 };
int i = 0;
while (1) {
arr[i] = 42;
if (i >= LEN-3) {
break;
}
else {
i += 3;
}
}
All this to avoid letting i exceed 10.
--
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 | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-12 04:30 -0500 |
| Message-ID | <kcraev$fv2$1@dont-email.me> |
| In reply to | #29990 |
On 1/11/2013 21:40, Keith Thompson wrote: > > Hardly. If I want to access every 10th element of an array, starting > from element 0, the above is a perfectly good way to do that. If the > array has 10 or fewer elements, it will access only element 0. If it > has 23 elements, it will access elements 0, 10, and 20, and then leave i > with the value 30. > > It *doesn't matter* that the value of i goes past the last valid index > of the array, as long as I don't use that value to index the array. The > upper bound for i is INT_MAX. > > (This is a significant difference between accessing arrays with integer > indices vs. using pointers, and one that hadn't occurred to be before. > It probably doesn't show up very often, we don't usually skip through > arrays like this.) >[...] > I'm tempted to suggest that you've misspelled "bogus". 8-)} > Ha ha ha, yes... From one beard-o to another: I could very well be misremembering. :)} I won't argue about the usefulness any more since it's subjective and because I can't seem to track down the exact warning or the explanatory web page that I recalled. When Syslinux was bitten by this warning (turned error because of -Werror), here're some numbers, for what they're worth: - I'm 100% certain that the diagnostic was issued and turned out to be a false positive, as there was no undefined behaviour in the code. - I'm 95% certain that the code involved was clearly explained by the web page explaining the cause of the false positive. - I'm 90% certain that the code was indeed a bit of an odd loop construct, and that reworking it could've avoided the false positive. - I'm 100% certain that the extra attention to the loop seemed warranted, but certainly didn't warrant aborting the build process, as was happening. - I'm 70% certain that the web page's explanation of the false positive was that the translation process treated the array index and pointer arithmetic in the same way, so the problem with a pointer pointing beyond one past was being misapplied to the index. - I'm 60% certain that an optimization level was involved. - I'm 70% certain that instead of changing the code, Syslinux chose to change the compilation options. - I'm 65% certain that FORTIFY_SOURCE was involved. Oh well, I give up. Heh. -- - Shao Miller -- "Thank you for the kind words; those are the kind of words I like to hear. Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web