From 84eea5bb1ff2540639825d3b147dbd4655aa5152 Mon Sep 17 00:00:00 2001 From: rolandreichweinbmw Date: Sat, 14 Dec 2024 22:36:15 +0100 Subject: [PATCH 1/2] Packed unaligned_type (#989) This way, unaligned_types like etl::be_uint32_t can be used in places where POD types are expected. --- include/etl/platform.h | 8 ++++++++ include/etl/unaligned_type.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/etl/platform.h b/include/etl/platform.h index e66a0e08d..f8d8752de 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -454,6 +454,14 @@ SOFTWARE. #define ETL_HAS_INITIALIZER_LIST 0 #endif +//************************************* +// Determine if the ETL should use __attribute__((packed). +#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) + #define ETL_PACKED __attribute__((packed)) +#else + #define ETL_PACKED +#endif + //************************************* // Check for availability of certain builtins #include "profiles/determine_builtin_support.h" diff --git a/include/etl/unaligned_type.h b/include/etl/unaligned_type.h index 9b4ae6629..77e38ce12 100644 --- a/include/etl/unaligned_type.h +++ b/include/etl/unaligned_type.h @@ -227,7 +227,7 @@ namespace etl ///\tparam Endian The endianness of the arithmetic type. //************************************************************************* template - class unaligned_type : public private_unaligned_type::unaligned_type_common + class ETL_PACKED unaligned_type : public private_unaligned_type::unaligned_type_common { public: From 05682930e1053bd4dd1a107df65d7c5fa83012c3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 16 Dec 2024 14:58:16 +0000 Subject: [PATCH 2/2] Make 'packed' have better cross platform functionality --- include/etl/platform.h | 13 +++++++++++-- include/etl/unaligned_type.h | 6 +++--- test/test_etl_traits.cpp | 1 + test/test_utility.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/etl/platform.h b/include/etl/platform.h index f8d8752de..d6975bc1a 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -456,10 +456,18 @@ SOFTWARE. //************************************* // Determine if the ETL should use __attribute__((packed). -#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) - #define ETL_PACKED __attribute__((packed)) +#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6) + #define ETL_PACKED __attribute__((packed)) + #define ETL_END_PACKED + #define ETL_HAS_PACKED 1 +#elif defined(ETL_COMPILER_MICROSOFT) + #define ETL_PACKED __pragma(pack(push, 1)) + #define ETL_END_PACKED __pragma(pack(pop)) + #define ETL_HAS_PACKED 1 #else #define ETL_PACKED + #define ETL_END_PACKED + #define ETL_HAS_PACKED 0 #endif //************************************* @@ -520,6 +528,7 @@ namespace etl static ETL_CONSTANT bool has_mutable_array_view = (ETL_HAS_MUTABLE_ARRAY_VIEW == 1); static ETL_CONSTANT bool has_ideque_repair = (ETL_HAS_IDEQUE_REPAIR == 1); static ETL_CONSTANT bool has_virtual_messages = (ETL_HAS_VIRTUAL_MESSAGES == 1); + static ETL_CONSTANT bool has_packed = (ETL_HAS_PACKED == 1); // Is... static ETL_CONSTANT bool is_debug_build = (ETL_IS_DEBUG_BUILD == 1); diff --git a/include/etl/unaligned_type.h b/include/etl/unaligned_type.h index 77e38ce12..1c406ba3c 100644 --- a/include/etl/unaligned_type.h +++ b/include/etl/unaligned_type.h @@ -53,7 +53,7 @@ namespace etl /// Contains all functionality that doesn't require the type. //************************************************************************* template - class unaligned_type_common + class ETL_PACKED unaligned_type_common { public: @@ -214,7 +214,7 @@ namespace etl protected: unsigned char storage[Size]; - }; + }; ETL_END_PACKED template ETL_CONSTANT size_t unaligned_type_common::Size; @@ -729,7 +729,7 @@ namespace etl } } }; - }; + }; ETL_END_PACKED template ETL_CONSTANT int unaligned_type::Endian; diff --git a/test/test_etl_traits.cpp b/test/test_etl_traits.cpp index a071960e4..24123ad3a 100644 --- a/test/test_etl_traits.cpp +++ b/test/test_etl_traits.cpp @@ -77,6 +77,7 @@ namespace CHECK_EQUAL((ETL_HAS_IDEQUE_REPAIR == 1), etl::traits::has_ideque_repair); CHECK_EQUAL((ETL_HAS_MUTABLE_ARRAY_VIEW == 1), etl::traits::has_mutable_array_view); CHECK_EQUAL((ETL_HAS_VIRTUAL_MESSAGES == 1), etl::traits::has_virtual_messages); + CHECK_EQUAL((ETL_HAS_PACKED == 1), etl::traits::has_packed); CHECK_EQUAL((ETL_IS_DEBUG_BUILD == 1), etl::traits::is_debug_build); CHECK_EQUAL(__cplusplus, etl::traits::cplusplus); diff --git a/test/test_utility.cpp b/test/test_utility.cpp index a1f28e950..5b3ce6587 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -666,5 +666,31 @@ namespace CHECK_EQUAL(forward_like_call_type::ConstRValue, template_function_fl(etl::move(u4))); CHECK_EQUAL(forward_like_call_type::ConstRValue, template_function_fl(etl::move(u4))); } + +#if ETL_HAS_PACKED + //********************************* + TEST(test_packed) + { + struct Unpacked + { + uint32_t a = 0x12345678; + uint8_t b = 0x9A; + uint32_t c = 0x87654321; + }; + + struct ETL_PACKED Packed + { + uint32_t a = 0x12345678; + uint8_t b = 0x9A; + uint32_t c = 0x87654321; + }; ETL_END_PACKED + + Unpacked unpacked; + Packed packed; + + CHECK_TRUE(sizeof(unpacked) > sizeof(packed)); + CHECK_EQUAL(9U, sizeof(packed)); + } +#endif }; }