如何结合static_assert与sizeof和stringify? [英] How to combine static_assert with sizeof and stringify?

查看:159
本文介绍了如何结合static_assert与sizeof和stringify?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

内存使用在我的应用程序是相当关键。因此,我有具体的断言,在编译时检查内存大小,并给出一个static_assert如果大小不同于我们认为正确之前。



我已经定义了一个宏像这样:

  #define CHECKMEM(mytype,size)static_assert((sizeof(objectType)== size)不正确的#mytype!); 

这个宏可以很容易写成:

  CHECKMEM(Book,144); 
CHECKMEM(图书馆,80);

问题是当这个static_assert关闭时,可能很难找出什么新的size应该是(例如通过使用隐藏的编译器选项/ d1 reportAllClassLayout)。
如果我可以包括实际大小,那么会更加方便,因此代替:


p>

会显示


! (预计144,大小为152)


我尝试这样写:

  #define CHECKMEM(mytype,size)static_assert((sizeof(objectType)== size)),size incorrect for#mytype! is#sizeof(mytype))); 

但是你不能在函数调用上使用stringize

我也试过添加双字符串技巧,如下所示:

  #define STR1(x)#x 
#define STR2(x)STR1(x)
#define CHECKMEM(mytype,size)static_assert(sizeof(objectType)== size) #mytype!(预期为#size,大小为STR2(sizeof(mytype))));

但不是打印 size is 152 打印 size是sizeof(Book)



有没有办法在static_assert中stringize结果sizeof?

解决方案

我将在函数模板上使用dispatching来执行检查:

  #include< cstddef> 

template< typename ToCheck,std :: size_t ExpectedSize,std :: size_t RealSize = sizeof(ToCheck)>
void check_size(){
static_assert(ExpectedSize == RealSize,Size is off!);
}

struct foo
{
char bla [16];
};

int main()
{
check_size< foo,8>();
return 0;
}

结果:

 在实例化'void check_size()[with ToCheck = foo; long unsigned int ExpectedSize = 8ul; long unsigned int RealSize = 16ul]':
bla.cpp:15:22:从这里需要
bla.cpp:5:1:error:static assertion failed:Size is off!

调试信息在回溯的模板参数中。



如果这真的更好,你必须决定,它还取决于编译器。它还允许您使用模板映射隐藏预期大小,总计到最大大小和其他奇异的东西。


Memory usage is quite critical in my application. Therefore I have specific asserts that check for the memory size at compile time and give a static_assert if the size is different from what we considered correct before.

I have defined a macro like this:

#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "!");

This macro makes it very easy to write this:

CHECKMEM(Book,144);
CHECKMEM(Library,80);

The problem is that when this static_assert goes off, it might be quite difficult to find out what the new size should be (e.g. by using the hidden compiler option "/d1 reportAllClassLayout"). It would be much handier if I could include the actual size, so instead of:

Size incorrect for Book!

It would show

Size incorrect for Book! (expected 144, size is 152)

I tried writing something like this:

#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " #sizeof(mytype) ")");

But you can't use the stringize (#) operator on a function call.

I also tried adding the double-stringize trick, like this:

#define STR1(x) #x 
#define STR2(x) STR1(x) 
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " STR2(sizeof(mytype)) ")");

But instead of printing size is 152 it prints size is sizeof(Book).

Is there a way to stringify the result of sizeof in a static_assert?

解决方案

I'd use dispatching on a function template to do the checking:

#include <cstddef>

template <typename ToCheck, std::size_t ExpectedSize, std::size_t RealSize = sizeof(ToCheck)>
void check_size() {
  static_assert(ExpectedSize == RealSize, "Size is off!");
}

struct foo
{
  char bla[16];
};

int main()
{
  check_size<foo, 8>();
  return 0;
}

Results in:

In instantiation of ‘void check_size() [with ToCheck = foo; long unsigned int ExpectedSize = 8ul; long unsigned int RealSize = 16ul]’:
bla.cpp:15:22:   required from here
bla.cpp:5:1: error: static assertion failed: Size is off!

The debugging information is in the template parameters of the back-trace.

If this is truly better, you will have to decide and it also depends on the compiler. It also enables you to hide the expected size with a template map, to sum up to a max size and other fancy things.

这篇关于如何结合static_assert与sizeof和stringify?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆