内存使用在我的应用程序中是非常关键的,因此我有一些特定的Assert,在编译时检查内存大小,如果大小与我们之前认为正确的大小不同,则给予一个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) ")");
但是不能在函数调用中使用字符串化(#)操作符。
我还尝试添加双字符串技巧,如下所示:
#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
。
有没有办法将static_assert中sizeof的结果字符串化?
7条答案
按热度按时间h9vpoimq1#
我将在函数模板上使用调度来执行检查:
结果:
调试信息位于反向跟踪的模板参数中。
如果这真的更好,你将不得不决定,这也取决于编译器。它还使你能够隐藏预期的大小与模板Map,以总结为一个最大大小和其他花哨的东西。
1rhkuytd2#
根据您的编译器,模板可能有助于:
海合会产出:
1tu0hz3e3#
正如您所发现的,问题就在这里(另请参见very similar question):
这是不可能的,因为字符串化是由预处理器完成的,并且sizeof是在编译期间计算的。
vaqhlq814#
这里的解决方案使编译器输出比较值和静态Assert中的特定消息。
因此,我们可以这样检查大小:
并获取Assert错误时的输出:
静态Assert失败:在示例化'struct uid_0::static_assert_size〈512,112,144〉'时需要更改impl_size:在宏“static_assert_size”的扩展中,“(512〈= 144)”在宏“static_assert_size”的扩展中计算为false
q8l4jmvw5#
如果您可以稍微修改结构体的定义,并且不介意有些难看的地方,那么这里有一个替代的只使用头文件的解决方案。
叮当声输出:
这里的一个警告是,只有在您示例化了某个类型的情况下才会进行检查--仅仅使用指针不会触发错误,因此肯定不是非常适合所有情况!
vlf7wbxs6#
一个简单实用的解决方案是使用2
static_assert
-s:inb24sb27#
如果您想将静态Assert放置在函数体之外(与the answer above相反),可以使用以下替代检查器:
Example用法: