2012-07-17 53 views
15

在我的应用程序中,内存使用情况非常关键。因此,我有特定的断言,在编译时检查内存大小,如果大小与我们之前认为正确的大小不同,则给出static_assert。如何将static_assert与sizeof和stringify结合起来?

我已经定义一个宏是这样的:

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

这个宏使得它很容易写:

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

的问题是,当这个static_assert熄灭,这可能是十分很难找出新的大小应该是什么(例如通过使用隐藏的编译器选项“/ d1 reportAllClassLayout”)。 如果我可以包含实际尺寸,将会更方便:

Book的尺寸不正确!

它会使

尺寸不正确的书! (预期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)

有没有办法在static_assert中对sizeof的结果进行字符串化?

+2

请注意'sizeof'不是函数调用 – 2012-07-17 16:13:34

+2

问题是'static_assert'的第二个参数必须是字符串文字,并且您不能在预处理器中构建它,因为您不能在其中使用sizeof 。 – pmr 2012-07-17 16:27:05

回答

17

我会使用调度上的功能模板做检查:

#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! 

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

如果这真的是更好的,你将不得不决定,它也取决于编译器。它还使您能够使用模板地图隐藏预期的大小,总结出最大尺寸和其他奇特的事物。

3

取决于你的编译器,模板可能能够帮助:

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" 
1

当你发现,该问题是在这里(另见本very similar question):

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

这是不可能的,因为字符串化是由prep rocessor和sizeof在编译过程中进行评估。

相关问题