When trying to build any example (I tested the first -AdvancedChatServer.ino) from the UIPEthernet library, the compiler issues hundreds of lines of similar messages about dereference warning
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip.c: In function 'uip_process':
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip_arp.c:116:24: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip_arp.c:253:20: note: in expansion of macro 'IPBUF'
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip.c:226:22: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip.c:755:6: note: in expansion of macro 'BUF'
BUF->flags = TCP_RST | TCP_ACK;
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip_arp.c:116:24: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip_arp.c:253:40: note: in expansion of macro 'IPBUF'
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip.c:226:22: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
^
/home/dmit/Arduino/libraries/UIPEthernet/utility/uip.c:781:6: note: in expansion of macro 'BUF'
BUF->flags = 0;
The reason for the warning is clear, the macros BUF... IPBUF, etc. are defined in the library as follows:
That is, in this case, a certain position in the symbolic buffer is rather roughly converted to the pointer type to the structure. Of course, this is invalid dereference in its pure form.
Actually, the question is not about the warning itself, but different - these warnings only appear when compiling the library on 32-bit boards, such as Due and the like. When building the same example on an 8-bit AVR, for example, Atmega2560 - there are no warnings. Is this connected with different compiler settings? Or is dereference somehow allowed on 8bit architectures?
And a separate question, is it possible to somehow fix the invalid dereferencing without rewriting the entire library?
Sorry, @Juraj, choosing another library is not a solution.
It is not my decision. My friend spent a lot of time to integrate UIPEthernet into his project. He asked me to help him remove these warnings. I can't tell him to spend a lot of time again remaking the project for another library.
If you are the maintainer of this library, help me to fix it.
The AVR compiler and ARM have a different backend, I believe they share the same parser. However, the AVR compiler is an older version I think. It might be a warning introduced in a later version.
I don't think it is anything to do with 8 bit vs 32 bit.
I guess you could just turn off the warning, unless you think it is an actual problem.
Unfortunately, I was asked to remove the reasons that lead to the occurrence of warning, and not just turn it off. Therefore, I would like to find a more adequate solution
Autor converts the pointer to the char buffer to a pointer to the structure. Are there any standard methods to replace this?
=======
To clarify the situation a little - I am not asking for ready-made code, I have quite of experience writing C++ projects.
I just suspect that there may be some standard approach to solving this problem, which for some reason I cannot find.
I did some more reading and I think you're not quite right.
The main reason why non-strict aliasing can lead to undefined behavior is alignment. In many 32-bit controllers, you can't assign a pointer to a multi-byte structure to an arbitrary memory address.
I think that's why this error appears on 32-bit architecture and is absent on 8-bit
Addition:
And if I'm right, this is not just an annoying warning, but the possibility of a very serious mistake. @Juraj , any comments?
No. The main reason is that the result of breaking the strict aliasing is undefined by the language standard. That means there is no specification for the object code produced by the compiler. In fact, it may produce no object code at all because there's no requirement for it to do so under this condition.
I don't know why the SAM platform has this check on. the old uip C library in core of UIPEthernet (and EthernetENC) library has the ethernet packet in a binary buffer and all over the library to work with the header of the packet it maps a struct on that memory location. this is not something that could be changed without a complete rewrite.
I assume that the libraries have been tested on all the platforms supported without issue.
In fact, the TCP/IP headers were designed so that they are inherently aligned where necessary. This was because many computers at the time (e.g. 32-bit minicomputers) did not support unaligned accesses. I am not sure that is still true of more recent protocols, but for the "standard" set I believe it is still true. This makes the warning probably moot.
The warning is just that, a warning, like many other C++ warnings. I think the intention of the compiler writers is to reserve the option to implement optimizations requiring strict aliasing in the future, even if not currently. Controversy arose over the decision to make strict-aliasing default to enabled, and much argument ensued; both sides are correct, but the compiler writers have the final say.
SAM (Cortex M3) does support unaligned access anyway. I think at least some Cortex-M0 do not, or only for certain instructions.
I looked into whether a library can have custom compilation options, it seems the only option would be for precompiled binaries.
In this case, I think the simplest thing to do is compile the project with -fno-strict-aliasing. This is what the Linux kernel does.