avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Re: sprintf


From: David Brown
Subject: [avr-gcc-list] Re: sprintf
Date: Fri, 06 Mar 2009 13:08:22 +0100
User-agent: Thunderbird 2.0.0.19 (Windows/20081209)

Joerg Wunsch wrote:
David Brown <address@hidden> wrote:

Rather than waffling more about what I thought or expected to
happen, I tried out a couple of cases.  I've pasted my test code at
the bottom of this post.

Thanks!

With avr-gcc 4.3.2, test3() below gave a "warning: array subscript is above array bounds" warning.

Yes, I can also see it.  As GCC 4.2 doesn't generate it, it appears to
be a relatively new feature of GCC.


Having a look at <http://gcc.gnu.org/gcc-4.3/changes.html> reveals a C-specific change:

-Warray-bounds has been added and is now enabled by default for -Wall . It produces warnings for array subscripts that can be determined at compile time to be always out of bounds. -Wno-array-bounds will disable the warning.


It was probably memories of reading this that first made me think gcc can treat array access differently from pointer arithmetic.

The same changes list shows that "0b" integers have now made it into mainline gcc from avr-gcc - wasn't that one of yours?

When taking the address of an array element or using pointer arithmetic, no warning is given. This makes sense as far as I understand the C standards - attempting to access an array beyond its bounds is illegal, but adding an integer to a pointer is always legal despite its values.

Nope.  Accessing something through a pointer that points into
unallocated memory causes undefined behaviour.  While the standard has
(of course) no guidelines for when to issue a warning, detecting
undefined behaviour would always warrant a warning.  Your example
shows, though, that GCC doesn't handle both situations the same (even
though it probably could).  This might or might not be easy to fix --
I'd leave that to those who understand the compiler better than me.
I'm happy enough to understand larger portions of the C standard. :-)


I thought calculating addresses with pointer arithmetic was always valid, but dereferencing them could be invalid (if the memory is unallocated). But that's a question for the comp.lang.c newsgroup...

I think you are right that many pointer-style accesses *could* be subject to the same sort of bound-checking as array accesses. However, I'm not sure that would be the right thing to do (I also expect it to be much harder to implement than with explicit array syntax). A pointer to a uint8_t could point *anywhere* - it's only invalid if it is pointing to unallocated memory. Checking that would be infeasible. The only reason I can think of for preferring pointer syntax over array access is when you want to do something a little funny with your pointers, and then you don't want potentially spurious compiler warnings.

The warnings are not yet perfect in gcc, however. For my array of size 4, it is legal to take the address &(as[4]) - no warning was given (code such as "return as[4];" correctly gave a warning). But neither was a warning given for "&(as[5])", and that is illegal code.

I also think that these warnings should in fact be errors - accessing arrays outside their bounds is clearly illegal code according to the standard, and there is an easy work-around if you want to force the compiler to break the rules.


With avr-gcc 4.2.2, foo1, foo2 and foo3 all generated the unrolled
loop, while foo4 generated the full loop above.

Yes, I also noticed this.  It also unrolls foo4() when compiling with
-O3.  Same for GCC 4.3, it also unrolls all loops with -O3.

The speed/size tradeoff is often based on heuristics, and
unfortunately (for us), these heuristics are usually determined on
GCC's mainstream targets so they don't fully apply to us.


These sorts of tradeoff usually result in a good compromise - make everyone equally unhappy :-) I expect there will always be cases where you get contradictions like -O3 generating smaller code than -Os. The "optimize" function attribute in gcc 4.4 will make it vastly easier to tune that sort of thing for critical code.


Neither compiler produced the smarter possibility:

        lds r24, as+1
        ldi r30, lo8(bs)
        ldi r31, hi8(bs)
        st Z+, r24
        st Z+, r24
        st Z+, r24
        st Z+, r24
        ret

Because apparantly, nobody has generated a pattern for that case.


I have no idea what sort of effort is needed to implement such a pattern, or whether it might be generally useful. If any of the experts thinks it is feasible to do, and realistic to think that someone might have the time to implement it, then I'll be happy to write it up as a "missed optimisation" bug report so it doesn't get lost.

mvh.,

David





reply via email to

[Prev in Thread] Current Thread [Next in Thread]