pw_checksum: Fix CRC32 linker issue - The CRC32 code fails to build in optimized builds. The inline keyword differs in meaning between C and C++. Inline C functions need to be declared static inline to link equivalently to an inline C++ function. Add static to the inline C function. - Expand some comments. Change-Id: I16a12bc0cbb666efbf5c479c6ff6a48d94ca5e1f Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/13840 Reviewed-by: David Rogers <davidrogers@google.com> Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_checksum/crc32.cc b/pw_checksum/crc32.cc index 76a18d0..e30d546 100644 --- a/pw_checksum/crc32.cc +++ b/pw_checksum/crc32.cc
@@ -64,13 +64,13 @@ } // namespace -extern "C" { - -uint32_t pw_ChecksumCrc32Append(const void* data, - size_t size_bytes, - uint32_t previous_result) { +extern "C" uint32_t pw_ChecksumCrc32Append(const void* data, + size_t size_bytes, + uint32_t previous_result) { const uint8_t* const array = static_cast<const uint8_t*>(data); + // CRC32 values are finalized by inverting the bits. The finalization step + // must be undone before appending to a prior CRC32 value. previous_result = ~previous_result; for (size_t i = 0; i < size_bytes; ++i) { @@ -80,5 +80,5 @@ return ~previous_result; } -} + } // namespace pw::checksum
diff --git a/pw_checksum/public/pw_checksum/crc32.h b/pw_checksum/public/pw_checksum/crc32.h index 340d8f7..9068206 100644 --- a/pw_checksum/public/pw_checksum/crc32.h +++ b/pw_checksum/public/pw_checksum/crc32.h
@@ -22,16 +22,19 @@ #define PW_CHECKSUM_CRC32_INITIAL_VALUE 0xFFFFFFFFu -// C API for calculating the ANSI CRC32 of an array of data. +// C API for calculating the CRC32 of an array of data. +// Updates an existing CRC value. The previous_result must have been returned +// from a previous CRC32 call; it is not used as the initial value. uint32_t pw_ChecksumCrc32Append(const void* data, size_t size_bytes, uint32_t previous_result); -inline uint32_t pw_ChecksumCrc32(const void* data, size_t size_bytes) { +// Starts calculating a CRC32 for the provided data. +static inline uint32_t pw_ChecksumCrc32(const void* data, size_t size_bytes) { return pw_ChecksumCrc32Append( data, size_bytes, ~PW_CHECKSUM_CRC32_INITIAL_VALUE); -}; +} #ifdef __cplusplus } // extern "C" @@ -42,26 +45,28 @@ inline constexpr uint32_t kCrc32InitialValue = PW_CHECKSUM_CRC32_INITIAL_VALUE; -// Calculates initial / one-time ANSI CRC32 for the provided data with standard -// initial value. +// Starts calculating a CRC32 with the provided data. Uses kCrc32InitialValue as +// the initial value. inline uint32_t Crc32(std::span<const std::byte> data) { return pw_ChecksumCrc32(data.data(), data.size_bytes()); } -// Update an existing CRC, pass the previous value as the value argument. +// Updates an existing CRC value. The previous_result must have been returned +// from a previous CRC32 call; it is not used as the initial value. inline uint32_t Crc32(std::span<const std::byte> data, uint32_t previous_result) { return pw_ChecksumCrc32Append( data.data(), data.size_bytes(), previous_result); } -// Calculates initial / one-time ANSI CRC32 for a single byte with standard -// initial value. This is useful for updating a CRC byte-by-byte. +// Starts calculating a CRC32 with the provided byte. Uses kCrc32InitialValue as +// the initial value. inline uint32_t Crc32(std::byte value) { return pw_ChecksumCrc32(&value, sizeof(value)); } -// Update an existing CRC, pass the previous value as the value argument. +// Updates an existing CRC value. The previous_result must have been returned +// from a previous CRC32 call; it is not used as the initial value. inline uint32_t Crc32(std::byte value, uint32_t previous_result) { return pw_ChecksumCrc32Append(&value, sizeof(value), previous_result); }