Skip to content

Commit 98e891f

Browse files
[libc++][string] Remove potential non-trailing 0-length array
It is a violation of the standard to use 0 length arrays, especially when not at the end of a structure (not a FAM GNU extension). Compiler generally accept it, but it's probably better to have a conforming implementation.
1 parent 04ab647 commit 98e891f

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

libcxx/include/string

+36-16
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,41 @@ struct __can_be_converted_to_string_view
748748
struct __uninitialized_size_tag {};
749749
struct __init_with_sentinel_tag {};
750750

751+
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
752+
template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
753+
struct __short_impl {
754+
_CharT __data_[__min_cap];
755+
unsigned char __padding_[_Padding];
756+
unsigned char __size_ : 7;
757+
unsigned char __is_long_ : 1;
758+
};
759+
760+
template <class _CharT, size_t __min_cap>
761+
struct __short_impl<_CharT, __min_cap, 0> {
762+
value_type __data_[__min_cap];
763+
unsigned char __size_ : 7;
764+
unsigned char __is_long_ : 1;
765+
};
766+
#else
767+
template <class _CharT, size_t __min_cap, size_t _Padding = sizeof(_CharT) - 1>
768+
struct __short_impl {
769+
struct _LIBCPP_PACKED {
770+
unsigned char __is_long_ : 1;
771+
unsigned char __size_ : 7;
772+
};
773+
char __padding_[_Padding];
774+
_CharT __data_[__min_cap];
775+
};
776+
template <class _CharT, size_t __min_cap>
777+
struct __short_impl<_CharT, __min_cap, 0> {
778+
struct _LIBCPP_PACKED {
779+
unsigned char __is_long_ : 1;
780+
unsigned char __size_ : 7;
781+
};
782+
_CharT __data_[__min_cap];
783+
};
784+
#endif
785+
751786
template <class _CharT, class _Traits, class _Allocator>
752787
class basic_string {
753788
private:
@@ -850,13 +885,6 @@ private:
850885

851886
enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
852887

853-
struct __short {
854-
value_type __data_[__min_cap];
855-
unsigned char __padding_[sizeof(value_type) - 1];
856-
unsigned char __size_ : 7;
857-
unsigned char __is_long_ : 1;
858-
};
859-
860888
// The __endian_factor is required because the field we use to store the size
861889
// has one fewer bit than it would if it were not a bitfield.
862890
//
@@ -899,17 +927,9 @@ private:
899927

900928
enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 };
901929

902-
struct __short {
903-
struct _LIBCPP_PACKED {
904-
unsigned char __is_long_ : 1;
905-
unsigned char __size_ : 7;
906-
};
907-
char __padding_[sizeof(value_type) - 1];
908-
value_type __data_[__min_cap];
909-
};
910-
911930
#endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
912931

932+
using __short = __short_impl<value_type, __min_cap>;
913933
static_assert(sizeof(__short) == (sizeof(value_type) * (__min_cap + 1)), "__short has an unexpected size.");
914934

915935
union __rep {

0 commit comments

Comments
 (0)