Do not memset(0) POD types

"POD" is the wrong type trait to determine if something can be safely
zero-filled in order to achieve zero initialization. Consider a type
like

  struct POD { int POD::*ptr; };

This is a POD; its value initialization needs to value initialize the
member, and since it's a pointer, that's zero initialization, and that's
setting the pointer to null.

On Itanium, a null pointer to data member is not zero filled; it actually
has the value -1u.

Hence, zero-filling via memset(0) a POD object like the one above is
erroneous. Unfortunately there is no type trait in C++ that we can use to
know if a given datatype can be value initialized by zero-filling -- we
can check for trivial constructability, but that's a necessary
condition, not a sufficient one (POD above is also trivially
constructible).

The test is disabled on MSVC because of a compiler bug.

Fixes #238
This commit is contained in:
Giuseppe D'Angelo
2023-01-27 12:37:17 +01:00
parent acc5b088f5
commit b694ada294
3 changed files with 25 additions and 7 deletions

View File

@@ -220,6 +220,12 @@ bool test_span_conversion()
#endif //BOOST_VECTOR_TEST_HAS_SPAN
struct POD { int POD::*ptr; };
BOOST_STATIC_ASSERT_MSG
( boost::container::dtl::is_pod<POD>::value
, "POD test failed"
);
int main()
{
{
@@ -392,5 +398,24 @@ int main()
);
}
////////////////////////////////////
// POD types should not be 0-filled testing
////////////////////////////////////
#if !defined(_MSC_VER)
// MSVC miscompiles value initialization of pointers to data members,
// https://developercommunity.visualstudio.com/t/Pointer-to-data-member-is-not-initialize/10238905
{
typedef boost::container::vector<POD> cont;
const std::size_t size = 10;
cont a(size);
for(std::size_t i = 0; i != size; ++i) {
if (a[i].ptr != 0) {
std::cerr << "POD test failed" << std::endl;
return 1;
}
}
}
#endif
return 0;
}