内存使用情况是在我的应用程序颇有微词。 因此,我有具体的断言检查编译时的内存大小,给予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?
我会用一个函数模板调度做的检查:
#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!
调试信息是在后面追踪的模板参数。
如果这是真的好,你将不得不决定,同时也依赖于编译器。 它还可以隐藏与模板地图的预期大小,总结到最大尺寸等花哨的东西。
根据你的编译器,模板可能能够帮助:
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"
当你发现了,问题是在这里(也看到这个非常类似的问题 ):
#define CHECKMEM(mytype, size) #sizeof(mytype)
这是不可能做到的,因为字串是由预处理完成的,而在编译过程中的sizeof进行评估。