如何static_assert用的sizeof结合和字符串化?(How to combine sta

2019-06-26 08:14发布

内存使用情况是在我的应用程序颇有微词。 因此,我有具体的断言检查编译时的内存大小,给予static_assert如果大小是从我们之前认为是正确的不同。

我已经定义了这样的宏:

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

这个宏使得它很容易写:

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

问题是,当这个static_assert熄灭,这可能是很难找到了什么新的大小应(例如,通过使用隐藏的编译器选项“/ D1 reportAllClassLayout”)。 这将是要容易上手得多,如果我可以包括实际大小,所以不是:

尺寸不正确的书!

它会显示

尺寸不正确的书! (预期144,大小为152)

我试着写是这样的:

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

但你不能使用stringize(#)运算符的函数调用。

我也尝试添加双stringize伎俩,就像这样:

#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)) ")");

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

有没有一种方法来字符串化的的sizeof结果在static_assert?

Answer 1:

我会用一个函数模板调度做的检查:

#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;
}

结果是:

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!

调试信息是在后面追踪的模板参数。

如果这是真的好,你将不得不决定,同时也依赖于编译器。 它还可以隐藏与模板地图的预期大小,总结到最大尺寸等花哨的东西。



Answer 2:

根据你的编译器,模板可能能够帮助:

template<int s, int t> struct check_size {
  static_assert(s == t, "wrong size");
};
check_size<2+2, 5> doubleplusungood;

GCC输出:

prog.cpp: In instantiation of 'check_size<4, 5>':
prog.cpp:5:20:   instantiated from here
prog.cpp:2:3: error: static assertion failed: "wrong size"


Answer 3:

当你发现了,问题是在这里(也看到这个非常类似的问题 ):

#define CHECKMEM(mytype, size)  #sizeof(mytype)

这是不可能做到的,因为字串是由预处理完成的,而在编译过程中的sizeof进行评估。



文章来源: How to combine static_assert with sizeof and stringify?