SChernykh/p2pool

Fail to build due to compile flag -Wcast-align

LithiumTins opened this issue · 1 comments

I tried to build p2pool on RISCV64 ArchLinux but failed. The errors are like:

/build/p2pool/src/p2pool/src/common.h: In member function ‘bool p2pool::raw_ip::operator==(const p2pool::raw_ip&) const’:
/build/p2pool/src/p2pool/src/common.h:443:37: error: cast from ‘const uint8_t*’ {aka ‘const unsigned char*’} to ‘const uint64_t*’ {aka ‘const long unsigned int*’} increases required alignment of target type [-Werror=cast-align]
  443 |                 const uint64_t* a = reinterpret_cast<const uint64_t*>(data);
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It seems the warning is caused by cast from uint8_t* to uint64_t* increases the alignment, and with -Wcast-align and -Werror the compilation is terminated.

I've carefully looked into this problem and found that:

  1. The compiler doesn't give out warnings on x86_64 no matter whether the alignment is increased and is well treated. However, it gives out warnings on RISCV64 when the alignment is increased even when the operand has been aligned as target type. For example, in the following code data is well-aligned and the warning above is still caused(the line number doesn't match):

    p2pool/src/common.h

    Lines 426 to 439 in 5988acb

    struct raw_ip
    {
    alignas(8) uint8_t data[16];
    FORCEINLINE bool operator<(const raw_ip& other) const
    {
    const uint64_t* a = reinterpret_cast<const uint64_t*>(data);
    const uint64_t* b = reinterpret_cast<const uint64_t*>(other.data);
    if (a[1] < b[1]) return true;
    if (a[1] > b[1]) return false;
    return a[0] < b[0];
    }
  2. I manually check every line that causes warning like this and almost all of them are well-aligned. There are some exceptions using function read_unaligned() in src\util.h , but I think it's ok because they do intend touse the pointer as an unaligned one. Here is one example:

    p2pool/src/p2p_server.cpp

    Lines 1600 to 1604 in 5988acb

    if (bytes_left >= 1 + sizeof(uint32_t)) {
    const uint32_t block_size = read_unaligned(reinterpret_cast<uint32_t*>(buf + 1));
    if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
    bytes_read = 1 + sizeof(uint32_t) + block_size;

Due to the reasons above, the compile flag -Wcast-align actually help nothing because the project indeed use casts that increase the alignment , while it does stop p2pool to build on RISCV64. Thus I suggest remove this compile flag.