Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > [MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?

Reply
Thread Tools

[MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?

 
 
Keith Thompson
Guest
Posts: n/a
 
      01-11-2013
Shao Miller <(E-Mail Removed)> writes:
> On 1/11/2013 11:19, Keith Thompson wrote:
>> Shao Miller <(E-Mail Removed)> writes:
>> [...]
>>> MUDFLAP can diagnose stuff that's permitted by C90, such as warning you
>>> that an index used for iteration has gone too far. Usually you want to
>>> index one-past an array, at most. Do the 'for' loops have any problems?

>>
>> As I'm sure you know, it's legal to construct a pointer one element
>> past the end of an array, but not to dererence it. Constructing a
>> pointer before the beginning of an array or more than one element
>> past the end of it, or deferencing a pointer one past the end of it,
>> has undefined behavior. I'm not aware of any relevant changes in
>> this area from C90 to C99 to C11.
>>
>> Are you saying that Mudflap complains about stuff that's legal *and
>> has defined behavior* in C90? If it complained about something
>> like this:
>>
>> int arr[N];
>> int *ptr;
>> for (ptr = arr; ptr < arr + N; ptr ++) {
>> /* ... */
>> }
>>
>> that would IMHO be a serious bug in Mudflap.
>>
>> (I haven't analyzed the posted code, but from the discussion I don't
>> think that's what's going on.)

>
> Nah, I tried to be careful and chose to type "index" instead of "point".
> The code I was criticizing used both an integer index as well as a
> pointer. Their pointer would never point more than one past the array,
> but their integer would index two past the array. That seems to be
> permitted by C90.


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.

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.

> I seem to recall some bit about this situation being easily detectable
> and reportable as a bonus diagnostic, perhaps in the hopes of alerting
> the programmer that there's a better way to write their loop without
> stepping out of bounds, conceptually.


What would such a diagnostic look like?

Warning: `i' exceeds the bounds of `arr', so evaluating `arr[i]'
would have undefined behavior, but that never happens so I'm not
sure what I'm warning you about.

A similar snippet using pointers *would* cause undefined behavior,
and would be worthy of a warning (though I can't quite persuade
gcc to generate one):

int arr[10] = { 0 };
int *ptr;
for (ptr = arr; ptr < arr + 10; ptr += 3) {
*ptr = 42;
}
return 0;

because it actually constructs the invalid pointer value.

Or am I missing something?

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
 
 
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-11-2013
Keith Thompson <(E-Mail Removed)> wrote:

(snip on variables that could be used to index outside an array)

> A similar snippet using pointers *would* cause undefined behavior,
> and would be worthy of a warning (though I can't quite persuade
> gcc to generate one):


> int arr[10] = { 0 };
> int *ptr;
> for (ptr = arr; ptr < arr + 10; ptr += 3) {
> *ptr = 42;
> }
> return 0;


> because it actually constructs the invalid pointer value.


Yes, the standard disallows this, but it is not likely to cause
problems on the usual implementations.

An implementation actually doing array bounds checking should catch
an attempt to derefernence that pointer.

I suppose I can imagine someone implementing bounds checking
such that it actually checks such, but I don't see why.

On most processors, the worst that happens is that a pointer overflows,
usually without any problem.

In the past, there were processors that with keyed storage, such
that it actually knew the type stored in any memory location.
Along with in appropriate implementation of pointers, this might
be caught in hardware.

-- glen

 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      01-12-2013
On 1/11/2013 17:04, Keith Thompson wrote:
> Shao Miller <(E-Mail Removed)> writes:
>> On 1/11/2013 11:19, Keith Thompson wrote:
>>> Shao Miller <(E-Mail Removed)> writes:
>>> [...]
>>>> MUDFLAP can diagnose stuff that's permitted by C90, such as warning you
>>>> that an index used for iteration has gone too far. Usually you want to
>>>> index one-past an array, at most. Do the 'for' loops have any problems?
>>>
>>> As I'm sure you know, it's legal to construct a pointer one element
>>> past the end of an array, but not to dererence it. Constructing a
>>> pointer before the beginning of an array or more than one element
>>> past the end of it, or deferencing a pointer one past the end of it,
>>> has undefined behavior. I'm not aware of any relevant changes in
>>> this area from C90 to C99 to C11.
>>>
>>> Are you saying that Mudflap complains about stuff that's legal *and
>>> has defined behavior* in C90? If it complained about something
>>> like this:
>>>
>>> int arr[N];
>>> int *ptr;
>>> for (ptr = arr; ptr < arr + N; ptr ++) {
>>> /* ... */
>>> }
>>>
>>> that would IMHO be a serious bug in Mudflap.
>>>
>>> (I haven't analyzed the posted code, but from the discussion I don't
>>> think that's what's going on.)

>>
>> Nah, I tried to be careful and chose to type "index" instead of "point".
>> The code I was criticizing used both an integer index as well as a
>> pointer. Their pointer would never point more than one past the array,
>> but their integer would index two past the array. That seems to be
>> permitted by C90.

>
> 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.

> 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.

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 seem to recall some bit about this situation being easily detectable
>> and reportable as a bonus diagnostic, perhaps in the hopes of alerting
>> the programmer that there's a better way to write their loop without
>> stepping out of bounds, conceptually.

>
> What would such a diagnostic look like?
>
> Warning: `i' exceeds the bounds of `arr', so evaluating `arr[i]'
> would have undefined behavior, but that never happens so I'm not
> sure what I'm warning you about.
>


Let me try to dig it up and post again...

> A similar snippet using pointers *would* cause undefined behavior,
> and would be worthy of a warning (though I can't quite persuade
> gcc to generate one):
>
> int arr[10] = { 0 };
> int *ptr;
> for (ptr = arr; ptr < arr + 10; ptr += 3) {
> *ptr = 42;
> }
> return 0;
>
> because it actually constructs the invalid pointer value.
>
> Or am I missing something?
>


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.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      01-12-2013
On 1/11/2013 19:30, Shao Miller wrote:
>
>>> I seem to recall some bit about this situation being easily detectable
>>> and reportable as a bonus diagnostic, perhaps in the hopes of alerting
>>> the programmer that there's a better way to write their loop without
>>> stepping out of bounds, conceptually.

>>
>> What would such a diagnostic look like?
>>
>> Warning: `i' exceeds the bounds of `arr', so evaluating `arr[i]'
>> would have undefined behavior, but that never happens so I'm not
>> sure what I'm warning you about.
>>

>
> Let me try to dig it up and post again...
>


I seem to recall that the introduction of FORTIFY_SOURCE caused some
sudden breakage for Syslinux, when Syslinux treated warnings as errors.
I've tried now for several minutes to find the nice explanation of the
conforming-but-warned-against loop situation that I'd seen before, but
I've not yet found it.

In the meanwhile, what I can do is to quote the patch:

"With -D_FORTIFY_SOURCE=2 some more checking is added, but some
conforming programs might fail." -- Jakub Jelinek

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-12-2013
Shao Miller <(E-Mail Removed)> wrote:
> On 1/11/2013 17:04, Keith Thompson wrote:


(snip)
>> 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.


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.)

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.)

>> 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)
> This example is a good one, and rings a bell as being along the lines of
> the bonus diagnostic I mentioned.


> 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.


No, other way around.

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.)

Because of that requirement it would certainly be allowed for an
implementation doing bounds checking to check that a pointer was
in range. Unless it is actually used to reference, fetch or store,
actual data, though, I wouldn't do it.

I used to do a lot of programming in 80286 protected mode with OS/2.

Well, all the modes are still there, but nobody uses them.

A segment descriptor describes a region in memory with an origin and
length, and any access using that descriptor is checked by the hardware.

When a (16 bit) segment selector is loaded into a segment register,
the appropriate descriptor is loaded into the correspending register.

Now, compilers won't load random date into segment registers, as it
will fail if the corresponding descriptor doesn't exist or is invalid.

There is, however, no restriction on the offset. That goes into an
ordinary register and is only checked when actual access is made to
data.

There is a hardware trap on fetch or store past the end of a segment.
I did a lot of debugging using that. OS/2 would put up a nice window
with the register contents at the time of the trap, making it fairly
easy to find.

However, in huge model it might cause problems. Personally, I avoid
huge if possible. Huge allows for arrays more than 64K (in 80286
mode) or more than 4GB (in 32 bit protected mode) by choosing a
segment selector based on the index. Even so, though, I would be
surprised to see the compiler actually do it. It can easily do the
computation in other registers, only loading the segment register
when actually addressing data.

Well, the big problem with doing this is that there is no cache
for segment descriptors. Every time you load a 16 bit selector
the processor has to also load a 64 bit descriptor from memory.
(Well, hopefully in processor cache, but still.)

With an appropriate in-processor descriptor cache it could have
been much faster. Enough to delay the need for 64 bit addressing.

--------------

It might be that some of the Burroughs machines from years past had
pointer registers that checked that they were in bounds.

But there should be no problem with a program indexing an integer
variable that could be used to access an array, as long as it isn't
actually used to access the array outside the bounds.

A compiler on a machine that did have that requirement would have
to be sure not to load such into the appropriate register until
it had been checked.

> Let me try to dig it up and post again...


>> A similar snippet using pointers *would* cause undefined behavior,
>> and would be worthy of a warning (though I can't quite persuade
>> gcc to generate one):


>> int arr[10] = { 0 };
>> int *ptr;
>> for (ptr = arr; ptr < arr + 10; ptr += 3) {
>> *ptr = 42;
>> }
>> return 0;


>> because it actually constructs the invalid pointer value.


-- glen
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-12-2013
glen herrmannsfeldt <(E-Mail Removed)> writes:

> Keith Thompson <(E-Mail Removed)> wrote:
>
> (snip on variables that could be used to index outside an array)
>
>> A similar snippet using pointers *would* cause undefined behavior,
>> and would be worthy of a warning (though I can't quite persuade
>> gcc to generate one):

>
>> int arr[10] = { 0 };
>> int *ptr;
>> for (ptr = arr; ptr < arr + 10; ptr += 3) {
>> *ptr = 42;
>> }
>> return 0;

>
>> because it actually constructs the invalid pointer value.

>
> Yes, the standard disallows this, but it is not likely to cause
> problems on the usual implementations.
>
> An implementation actually doing array bounds checking should catch
> an attempt to derefernence that pointer.
>
> I suppose I can imagine someone implementing bounds checking
> such that it actually checks such, but I don't see why.
>
> On most processors, the worst that happens is that a pointer overflows,
> usually without any problem.


If you combine these last to you get a reason to see why you might want
to check the pointer. If an implementation wants to do bounds checking,
yet pointers can wrap round to "safe" values, you need to check the
pointer generation and not just the access.

<snip>
--
Ben.
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      01-12-2013
On 1/11/2013 20:17, glen herrmannsfeldt wrote:
> Shao Miller <(E-Mail Removed)> wrote:
>> On 1/11/2013 17:04, Keith Thompson wrote:

>
> (snip)
>>> 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.

>
> 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.

> 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.

>>> 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)
>> This example is a good one, and rings a bell as being along the lines of
>> the bonus diagnostic I mentioned.

>
>> 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.

>
> No, other way around.
>
> 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.)
>


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!).

> Because of that requirement it would certainly be allowed for an
> implementation doing bounds checking to check that a pointer was
> in range. Unless it is actually used to reference, fetch or store,
> actual data, though, I wouldn't do it.
>
> I used to do a lot of programming in 80286 protected mode with OS/2.
>
> Well, all the modes are still there, but nobody uses them.
>
> A segment descriptor describes a region in memory with an origin and
> length, and any access using that descriptor is checked by the hardware.
>
> When a (16 bit) segment selector is loaded into a segment register,
> the appropriate descriptor is loaded into the correspending register.
>
> Now, compilers won't load random date into segment registers, as it
> will fail if the corresponding descriptor doesn't exist or is invalid.
>
> There is, however, no restriction on the offset. That goes into an
> ordinary register and is only checked when actual access is made to
> data.
>
> There is a hardware trap on fetch or store past the end of a segment.
> I did a lot of debugging using that. OS/2 would put up a nice window
> with the register contents at the time of the trap, making it fairly
> easy to find.
>
> However, in huge model it might cause problems. Personally, I avoid
> huge if possible. Huge allows for arrays more than 64K (in 80286
> mode) or more than 4GB (in 32 bit protected mode) by choosing a
> segment selector based on the index. Even so, though, I would be
> surprised to see the compiler actually do it. It can easily do the
> computation in other registers, only loading the segment register
> when actually addressing data.
>
> Well, the big problem with doing this is that there is no cache
> for segment descriptors. Every time you load a 16 bit selector
> the processor has to also load a 64 bit descriptor from memory.
> (Well, hopefully in processor cache, but still.)
>
> With an appropriate in-processor descriptor cache it could have
> been much faster. Enough to delay the need for 64 bit addressing.
>
> --------------
>
> It might be that some of the Burroughs machines from years past had
> pointer registers that checked that they were in bounds.
>
> But there should be no problem with a program indexing an integer
> variable that could be used to access an array, as long as it isn't
> actually used to access the array outside the bounds.
>
> A compiler on a machine that did have that requirement would have
> to be sure not to load such into the appropriate register until
> it had been checked.
>


Right. It's not that there's an actual problem with the operation,
it's a diagnostic for the senselessness of the code.

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-12-2013
glen herrmannsfeldt <(E-Mail Removed)> 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) (E-Mail Removed) <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"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-12-2013
Shao Miller <(E-Mail Removed)> 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". }

> 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) (E-Mail Removed) <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"
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      01-12-2013
Shao Miller <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Warning:Xst:382 - Register A is equivalent to B mag VHDL 1 05-19-2005 05:10 PM
instancename of current entity/architecture -- equivalent to C++ this??? Eric Peers VHDL 2 11-18-2004 05:23 PM
VHDL equivalent of verilog trireg Sanjeev VHDL 4 07-23-2004 09:55 AM
equivalent types in different packages Lolo VHDL 3 09-22-2003 03:23 PM
Re: Image Scanning - TWAIN equivalent Brendan Duffy ASP .Net 0 07-24-2003 08:29 AM



Advertisments