Если я правильно понял суть вопроса, то могу предложить один вариант. Скажем, будем считать CRC32 на этапе компиляции (тема бородатая, делается легко). Предположим, что 11 стандарта на руках нету.
В первую очередь надо взять строку от определения структуры. Сделать это можно так:
#define TOSTR( V ) #V
#define MKSTR( V ) TOSTR( V )
#define STRINGIFY_BODY( STR_NAME, ... ) \
static const char* STR_NAME = MKSTR( __VA_ARGS__ ); \
__VA_ARGS__
STRINGIFY_BODY( MY_STRUCT_STR,
struct MyStruct {
uint32_t m_field1;
int16_t m_field2;
int64_t m_field3;
}
);
Конечно-же, сама строка нам тут не нужна, а нужна именно CRC32. Да при том, посчитанная в compile-time.
Для этого вводим в свой код такой вот ужас:
static const uint32_t CRC32_TABLE[256] = {
... // тут много констант.
};
template< int pos >
__forceinline uint32_t make_crc32( const char* data ){
const uint32_t crc = make_crc32< pos - 1 >( data );
return ( crc >> 8 ) ^ CRC32_TABLE[ ( crc ^ data[ pos ] ) & 0x000000FFU ];
};
template<>
__forceinline uint32_t make_crc32<-1>( const char* data ){
return 0xFFFFFFFFU;
};
// -1 будет указывать на концевой ноль строки,
// а -2 - в самую пору для начала подсчета - это последний символ строки.
#define GET_CRC32( V ) ( make_crc32< sizeof( V ) - 2 >( V ) ^ 0xFFFFFFFFU )
В самом подсчете суммы я мог наломать дров, точностей на скорую руку не помню. Поправьте меня, если не так.
Что это за код.
"__forceinline" - специальное слово для MSVC++ компилятора, указывающее принудительное развертывание этого кода. Работает это слово только при включенной оптимизации.
Шаблон "make_crc32" будет инстанцирован столько раз, какая в коде встретится максимальная длина строки. В релизе шаблоны "make_crc32" будут схлопнуты в значения, а табличка "CRC32_TABLE" будет вырезана из бинарника за ненадобностью. Контрольная сумма посчитатся при сборке проекта.
Теперь осталось только дописать макрос стрингификатор.
#define STRINGIFY_BODY( CRC_NAME, ... ) \
static const uint32_t CRC_NAME = GET_CRC32( MKSTR( __VA_ARGS__ ) ); \
__VA_ARGS__
А использовать теперь этот стрингификатор можно вот так:
STRINGIFY_BODY( MY_STRUCT_CRC,
struct MyStruct {
static const uint32_t H;
uint32_t m_field1;
int16_t m_field2;
int64_t m_field3;
}
);
const uint32_t MyStruct::H = MY_STRUCT_CRC;
...или как-либо иначе. Идея, в общем, нарисовалась вот такая.
От __forceinline можно избавиться в пользу constexpr (для случая с 11 стандартом), результат должен быть таким же.
В релизе breakpoint внутри подсчета CRC32 не сработает, т.к. все уже посчитано, а в дебаге будет работать (если в дебаге оптимизация не включена).