编译时断言以确定指针是否为数组 [英] Compile-time assertion to determine if pointer is an array
问题描述
当前,我有以下代码块可以进行安全的字符串复制(它可以正常工作):
Currently, I have the following block of code to make safe string copying (it works):
#define STRCPY(dst, src) do { assert(((void*)(dst)) == ((void*) & (dst))); \
strlcpy(dst, src, sizeof(dst)); } while (0)
因此,它接受如下构造:
So it accepts the construction like:
const char *src = "hello";
char dest[5];
STRCPY(dest, src); //hell
并拒绝以下内容:
void (char *dst) {
STRCPY(dst, "heaven"); //unknown size of dst
}
问题在于代码块创建了一个断言.有没有办法在编译时执行此检查?
The problem is that the block of code creates an assertion. Is there a way to perform this check on compilation time?
所以我想在编译时出错(例如使用负数),而不是崩溃(如果可能).
So I want to have the error on compilation (like creating an array with negative size) instead of crashing code if it possible.
推荐答案
要在编译时声明 dst
是否为数组,如果C11可用,我将使用@Lundin解决方案(或 _Static_assert
).
For compile-time assertion on whether or not dst
is an array,
I would use @Lundin solution (or _Static_assert
) in case C11 is available.
否则,我将使用以下内容:
Else, I would use the following:
#define BUILD_BUG_ON_NON_ARRAY_TYPE(e)(sizeof(struct {int:-!!(((void *)(e))!=((void *)&(e));})))
基本上采用编译时评估的表达式(((void *)(dst))==((void *)&(dst))
,但不要在运行时使用它 assert
只是以编译时断言的方式使用它.
Which basically takes your compile-time evaluated expression ((void*)(dst)) == ((void*) & (dst))
but instead of using it in run time assert
just use it in a compile-time assertion manner.
因此,总的来说,我会将您的宏更改为:
So, overall I would change your macro into:
#define STRCPY(dst, src) do { BUILD_BUG_ON_NON_ARRAY_TYPE(dst); \
strlcpy(dst, src, sizeof(dst)); } while (0)
这篇关于编译时断言以确定指针是否为数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!