jeudi 25 août 2022

Why the tuple has a larger size than expected?

I had the following definition of a tuple class template and tests for its size.

template <typename...> struct Tuple;

template <> struct Tuple<> {};

template <typename Head, typename... Tail>
struct Tuple<Head, Tail...> : Tuple<Tail...>
{
  Tuple(const Head& head, const Tail&... tail)
    : Base{ tail... }, m_head{ head } {}

private:
  using Base = Tuple<Tail...>;
  Head m_head;
};

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>

struct Nil {};

TEST_CASE("test size")
{
  using T0 = Tuple<>;
  CHECK(sizeof(T0) == 1);

  using T1 = Tuple<double, std::string, int, char>;

  struct Foo
  {
    double d;
    std::string s;
    int i;
    char c;
  };

  CHECK(sizeof(T1) == sizeof(Foo));

  using T2 = Tuple<int*, Nil>;
  CHECK(sizeof(T2) == sizeof(int*));

  using T3 = Tuple<int*, Nil, Nil>;
  CHECK(sizeof(T3) == sizeof(int*));
}

I expect because of the empty base class optimization the T2 and T3 tuples to be a pointer size, but the result is different.

[doctest] doctest version is "2.4.9"
[doctest] run with "--help" for options
===============================================================================
C:\projects\cpp\cpp_programming_language\28_metaprogramming\variadic_tuple.cpp(21):
TEST CASE:  test size

C:\projects\cpp\cpp_programming_language\28_metaprogramming\variadic_tuple.cpp(39): ERROR: CHECK( sizeof(T2) == sizeof(int*) ) is NOT correct!
  values: CHECK( 16 == 8 )

C:\projects\cpp\cpp_programming_language\28_metaprogramming\variadic_tuple.cpp(42): ERROR: CHECK( sizeof(T3) == sizeof(int*) ) is NOT correct!
  values: CHECK( 16 == 8 )

===============================================================================
[doctest] test cases: 1 | 0 passed | 1 failed | 0 skipped
[doctest] assertions: 4 | 2 passed | 2 failed |
[doctest] Status: FAILURE!

Why is this and is it possible somehow to enable the empty base class optimization?

Aucun commentaire:

Enregistrer un commentaire