Максимальный размер типа во время компиляции
От: GhostCoders Россия  
Дата: 28.10.15 19:05
Оценка:
Добрый вечер!

Есть небор типов (различных структур С++), необходимо найти размер максимальной структуры:

struct A
{
    char field_a;

    A(): field_a('a') {}
};

struct B
{
    double c;

    B() : c(10.0) {}
};

struct D
{
    int buffer[100];

    D()
    {
      //... some code...
    }
};


В этом примере максимальный развер структуры — 400 байт (структура D).

union не помогает, так как в каждой структуре есть свой конструктор.

Может как-то через boost::mpl::list ?
Или что попроще придумать?
Третий Рим должен пасть!
Re: Максимальный размер типа во время компиляции
От: GhostCoders Россия  
Дата: 28.10.15 19:13
Оценка:
Сейчас использую несколько вложенных boost::static_unsigned_max, но немного уродливо:

boost::static_unsigned_max<sizeof(A),boost::static_unsigned_max<sizeof(B),sizeof(D)>::value >::value;
Третий Рим должен пасть!
Re: Максимальный размер типа во время компиляции
От: watchmaker  
Дата: 28.10.15 19:33
Оценка: 2 (1) +2
Здравствуйте, GhostCoders, Вы писали:

GC>Есть небор типов (различных структур С++), необходимо найти размер максимальной структуры:

GC>Или что попроще придумать?
template <typename T>
const constexpr size_t MaxSize() {
  return sizeof(T);
}

template <typename u, typename v, typename... sz>
const constexpr size_t MaxSize() {
  return sizeof(u) > sizeof(v) ? MaxSize<u, sz...>() : MaxSize<v, sz...>();  
}

Использование, например:
MaxSize<A, B, D>()

или
char CommonBuffer[MaxSize<A, B, D>()];
Re: Максимальный размер типа во время компиляции
От: VTT http://vtt.to
Дата: 28.10.15 19:49
Оценка: 1 (1) +1
unrestricted union не вариант?
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re: Максимальный размер типа во время компиляции
От: Evgeny.Panasyuk Россия  
Дата: 28.10.15 20:12
Оценка: 2 (1)
Здравствуйте, GhostCoders, Вы писали:

GC>Может как-то через boost::mpl::list ?


В документации есть пример именно на эту тему:
typedef vector<int,long,char,char[50],double> types;
typedef max_element
<
    transform_view< types, sizeof_<_> >
>::type iter;

BOOST_MPL_ASSERT_RELATION( deref<iter>::type::value, ==, 50 );


GC>Или что попроще придумать?


Зависит от задачи. (например может быть достаточно готового Boost.Variant)
Отредактировано 28.10.2015 20:16 Evgeny.Panasyuk . Предыдущая версия . Еще …
Отредактировано 28.10.2015 20:14 Evgeny.Panasyuk . Предыдущая версия .
Re: Максимальный размер типа во время компиляции
От: LaptevVV Россия  
Дата: 28.10.15 20:31
Оценка: -2
GC>Есть небор типов (различных структур С++), необходимо найти размер максимальной структуры:
GC>В этом примере максимальный размер структуры — 400 байт (структура D).
GC>union не помогает, так как в каждой структуре есть свой конструктор.
Максимальный размер ты нашел.
Причем здесь union?
Тебе не размер нужен, а что?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Максимальный размер типа во время компиляции
От: swingus  
Дата: 28.10.15 23:13
Оценка: 2 (1)
Если на C++ 14, то можно без рекурсии.


#include <iostream>
#include <algorithm>
#include <initializer_list>
 
using namespace std;
 
struct A
{
    char field_a;
 
    A(): field_a('a') {}
};
 
struct B
{
    double c;
 
    B() : c(10.0) {}
};
 
struct D
{
    int buffer[100];
 
    D()
    {
    }
};
 
template <typename... Types>
constexpr auto get_sizes() 
{
    return initializer_list<size_t>{ sizeof(Types)... };
}
 
int main()
{
    cout << max( get_sizes<A, B, D>() ) << endl; 
}


Правда, я попробовал на VC++ онлайн компиляторе, код скомпилировался, но выдал какую-то ерунду. А вот на GCC всё OK.
Re: Максимальный размер типа во время компиляции
От: kov_serg Россия  
Дата: 29.10.15 01:17
Оценка: 132 (9) +2
Здравствуйте, GhostCoders, Вы писали:

GC>
GC>struct A
GC>{
GC>    char field_a;

GC>    A(): field_a('a') {}
GC>};

GC>struct B
GC>{
GC>    double c;

GC>    B() : c(10.0) {}
GC>};

GC>struct D
GC>{
GC>    int buffer[100];

GC>    D()
GC>    {
GC>      //... some code...
GC>    }
GC>};
GC>


GC>В этом примере максимальный развер структуры — 400 байт (структура D).


GC>union не помогает, так как в каждой структуре есть свой конструктор.

Просто вы не умеете его готовить.
union E { char a[sizeof(A)], b[sizeof(B)], d[sizeof(D)]; };
...
char buf[sizeof(E)];
Re[2]: Максимальный размер типа во время компиляции
От: Alexander G Украина  
Дата: 01.11.15 14:27
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Просто вы не умеете его готовить.

_>
_>union E { char a[sizeof(A)], b[sizeof(B)], d[sizeof(D)]; };
_>...
_>char buf[sizeof(E)];
_>


А как быть с выравниванием?
Русский военный корабль идёт ко дну!
Re: Максимальный размер типа во время компиляции
От: T4r4sB Россия  
Дата: 01.11.15 18:53
Оценка:
Здравствуйте, GhostCoders, Вы писали:

Я чёто туплю и не вижу подвоха наверное, почему нельзя тупо просто в лоб?
#define max(a,b) ((a)>(b)?(a):(b))

const int ms = max(max(sizeof(A), sizeof(B)), sizeof(C));
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[3]: Максимальный размер типа во время компиляции
От: T4r4sB Россия  
Дата: 01.11.15 18:56
Оценка: 4 (1)
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, kov_serg, Вы писали:



AG>А как быть с выравниванием?

union E
{ 
  char a[sizeof(A)], 
  b[sizeof(B)], 
  d[sizeof(D)]; 

  tblib::Align<A> aa;
  tblib::Align<B> ab;
  tblib::Align<D> ad;
};


  Велосипед для бустофобов
#pragma once
#include "stdint.h"
namespace tblib 
{
    template <typename T>
    struct _CheckAlign
    {
        uint8_t c;
        T t;
        _CheckAlign();
        _CheckAlign(const _CheckAlign&);
        _CheckAlign&operator=(const _CheckAlign&);
    };

    template <typename T>
    struct _AlignValue
    {
        enum { value = sizeof(_CheckAlign<T>)-sizeof(T) };
    };

    template <int N>
    struct _AlignBySize;

    template <> 
    struct _AlignBySize<1> { uint8_t  guts; };

    template <> 
    struct _AlignBySize<2> { uint16_t guts; };

    template <> 
    struct _AlignBySize<4> { uint32_t guts; };

    template <> 
    struct _AlignBySize<8> { uint64_t guts; };

    template <typename T>
    struct Align
    {
        _AlignBySize<_AlignValue<T>::value> guts;
    };
};
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Максимальный размер типа во время компиляции
От: GhostCoders Россия  
Дата: 01.11.15 19:27
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, GhostCoders, Вы писали:


TB>Я чёто туплю и не вижу подвоха наверное, почему нельзя тупо просто в лоб?

TB>
TB>#define max(a,b) ((a)>(b)?(a):(b))

TB>const int ms = max(max(sizeof(A), sizeof(B)), sizeof(C));
TB>


В принципе я так и делал, только через boost.

Вообщем, всем спасибо за помощь, я лаже не ожидал, что будет столько толковых ответов!

но... вообщем, исходная задача изменилась (вернее подход к ее решению) и теперь мне вообще это не требуется (т.е. максимальный размер типа).
Третий Рим должен пасть!
Re[3]: Максимальный размер типа во время компиляции
От: uzhas Ниоткуда  
Дата: 02.11.15 07:16
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>А как быть с выравниванием?


уточните где вы увидели проблемы с выравниванием?
Re[4]: Максимальный размер типа во время компиляции
От: Alexander G Украина  
Дата: 02.11.15 08:04
Оценка:
Здравствуйте, uzhas, Вы писали:

U>уточните где вы увидели проблемы с выравниванием?


Юнион вообще не выравнивается, тогда как содержащиеся типы могут требовать выравнивание.

Для гарантированного воспроизведения проблемы сделать, чтобы наибольший тип имел нечётный размер, и разместить два таких юниона подряд в структуре или массиве:

#include <stdio.h>
using namespace std;

struct A
{
    int a;
};

struct B
{
    char b[9];
};

union U
{
    char a[sizeof(A)];
    char b[sizeof(B)];
};

int main() {
    U u[2];
    printf("%p, %p", &(((A*)(&u[0].a))->a), &(((A*)(&u[1].a))->a) );
    return 0;
}
Русский военный корабль идёт ко дну!
Re[5]: Максимальный размер типа во время компиляции
От: uzhas Ниоткуда  
Дата: 02.11.15 08:22
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, uzhas, Вы писали:


U>>уточните где вы увидели проблемы с выравниванием?


AG>Юнион вообще не выравнивается,

возможно, я не понял эту фразу, но union выравнивается под наибольший мембер, то бишь он правильно выравнен для доступа к любому полю
можно почитать в гугле: http://stackoverflow.com/questions/8625368/alignment-of-variable-in-union

AG> тогда как содержащиеся типы могут требовать выравнивание.

в наших примерах в union содержатся только массивы char, для которых требование к выравниванию равно 1

AG>Для гарантированного воспроизведения проблемы сделать, чтобы наибольший тип имел нечётный размер, и разместить два таких юниона подряд в структуре или массиве:

"нечетный размер" — это уже говорит о непонимании выравнивания. размер и требования на выравнивание — разные вещи. для char[N] требование на выравнивание равно 1

пример: http://ideone.com/WfuIDc
Отредактировано 02.11.2015 8:29 uzhas . Предыдущая версия .
Re[6]: Максимальный размер типа во время компиляции
От: Alexander G Украина  
Дата: 02.11.15 08:54
Оценка: +1
Здравствуйте, uzhas, Вы писали:

AG>>Юнион вообще не выравнивается,

U>возможно, я не понял эту фразу, но union выравнивается под наибольший мембер, то бишь он правильно выравнен для доступа к любому полю

Я про состоящий из char.

AG>> тогда как содержащиеся типы могут требовать выравнивание.

U>в наших примерах в union содержатся только массивы char, для которых требование к выравниванию равно 1

Вот именно. Но мы то собираемся помещать и доставать типы, sizeof для которых взяли.
Разумеется, можно не конструировать через placement new, и не доставать кастом, а всегда использовать memcpy, но это уже противоречит цели union.
Русский военный корабль идёт ко дну!
Re[7]: Максимальный размер типа во время компиляции
От: uzhas Ниоткуда  
Дата: 02.11.15 09:08
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Но мы то собираемся помещать и доставать типы, sizeof для которых взяли.


вот это поворот, моей телепатии не хватило, чтобы предвидеть это
могу тогда предложить посмотреть aligned_storage: http://en.cppreference.com/w/cpp/types/aligned_storage
Re[8]: Максимальный размер типа во время компиляции
От: andyp  
Дата: 02.11.15 09:22
Оценка:
Здравствуйте, uzhas, Вы писали:

U>вот это поворот, моей телепатии не хватило, чтобы предвидеть это

U>могу тогда предложить посмотреть aligned_storage: http://en.cppreference.com/w/cpp/types/aligned_storage

Или это
http://en.cppreference.com/w/cpp/types/aligned_union
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.