verbose errors during compiling (not an issue)

sumotoy

Well-known member
Teensy3, IDE 1.15, Teeny 1.16, Win7/64Bit
I'm able to reproduce only temp has trashed and verbose in compilig enabled
First time I press compile:

Code:
In file included from D:\M\Arduino-1.15TR16\hardware\teensy\cores\teensy3\math_helper.h:33:0,from D:\M\Arduino-1.15TR16\hardware\teensy\cores\teensy3\math_helper.c:39:
D:\M\Arduino-1.15TR16\hardware\teensy\cores\teensy3\arm_math.h: In function 'arm_pid_q15':
D:\M\Arduino-1.15TR16\hardware\teensy\cores\teensy3\arm_math.h:5329:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

Subsequential compile not show any error so it's not really an issue but maybe can help to know...
 
TL;DR: That's a harmless warning.

Usually this warning happen when a pointer to char (8 bits data) is used to access 16 or 32 bit data, or converted to a different pointer type that could later be used that way. Even if that never actually happens, the compiler can't predict what most code will do when it runs.

On Teensy3, it's inefficient but usually ok to access "unaligned" data. For example, if you access a 32 bit integer at location 0x20000101, the processor will read the memory twice. It has a 32 bit bus to the memory, but the 32 wires are aligned with 32 bit offsets within the memory. The first read will fetch the 3 bytes at 0x20000101 to 0x20000103, then the second read will fetch the last byte at 0x20000104.

The compiler tries very hard to align data, partly for efficiency, but also because unaligned access is sometimes not ok. On Teensy3, the peripherals don't support unaligned access, and some don't even support reads or writes at different sizes (eg, a 32 bit register must be read as 32 bits, not bus cycle that reads only 8 or 16 of the 32 bits). Normally you don't ever worry about that stuff, partly because code in Teensyduino or libraries does most of the hardware register access, but also partly because the register definitions automatically force the correct access types if you use the published register names.

But some other 32 bit processors, like the Cortex M0, do not support unaligned access at all. If you ever make any unaligned access on those chips, it's a hard fault which effectively ends your program's execution. Those warnings are probably motivated by the less forgiving unaligned behavior of those other chips!

These warnings are fairly common. I believe there's one lurking in the Ethernet library or its support stuff in the core library. Sometimes code written for one type of chip (like AVR) where these warnings don't exist gets ported to another. Over time, the compiler has improved at detecting these cases, so sometimes older code that should have had such a warning gets it when built with a newer version of the compiler. In many cases, there's no possibility of unaligned access, but the compiler can't know the larger scheme of things, so it warns based on some type of pointer conversion or usage. Some programmers don't bother to look at the warnings.

I've had my eye on fixing these particular warnings, but that code in ARM's math library is quite complicated and some involves inline assembler. Eventually I'll fix it, but this is a very low priority right now.

While annoying, you can generally ignore this particular "type-punned pointer" warning.
 
TL;DR: That's a harmless warning.

Usually this warning happen when a pointer to char (8 bits data) is used to access 16 or 32 bit data, or converted to a different pointer type that could later be used that way. Even if that never actually happens, the compiler can't predict what most code will do when it runs.

On Teensy3, it's inefficient but usually ok to access "unaligned" data. For example, if you access a 32 bit integer at location 0x20000101, the processor will read the memory twice. It has a 32 bit bus to the memory, but the 32 wires are aligned with 32 bit offsets within the memory. The first read will fetch the 3 bytes at 0x20000101 to 0x20000103, then the second read will fetch the last byte at 0x20000104.

However, we've seen cases where higher levels of optimization (-O3) and newer compilers can trigger these latent bugs. As you mention, some things don't support unaligned accesses (or sometimes an unaligned access can trigger multiple I/Os, which might be a problem).

IIRC, ethernet libraries like unaligned accesses, because they put the ethernet header before the buffer, and the header is not always a convenient power of 2. So all of the data becomes unaligned.
 
This warning is not about unaligned access. The code in question casts a q15_t* to int32_t* which violates the aliasing rules. The aliasing rules mean that a q15_t* cannot point to a int32_t*. The compiler may use that 'knowledge' to make certain optimizations (e.g. optimize away assignments, reorder things, skip register reloads from memory, ...) and may miscompile things. GCC certainly does that in some instances and the warning is telling you that you are playing russian roulette.

GCC has a special type attribute '__may_alias__' for exactly this kind of use case or the compiler switch '-fno-strict-aliasing'.

BTW, char* pointers are an exception to the type-based aliasing and can alias anything by default.
 
Last edited:
Thanks guys for explanations, I knew was not an issue but good to learn something new about unaligned access and aliasing rules... :rolleyes:
 
Back
Top