使用复合文字数组作为临时字符串缓冲区合理吗?

问题描述 投票:0回答:1

我经常希望有一种简单的方法来使用 sprintf/snprintf 构造字符串,而无需定义本地数组的麻烦,如下所示:

char str[256];
snprintf(str, sizeof(str), format, ...);
use_string(str);

我突然想到我可以使用复合文字来做到这一点:

static inline char* snprintf_assert(char* str, int max_size, const char* format, ...) {
    va_list arg;
    va_start(arg, format);
    int count = vsnprintf(str, max_size, format, arg);
    va_end(arg);
    assert(count >= 0 && count < max_size);
    return str;
}

// Helper sprintf that allocates a buffer local to the block.
// It's using the fact that (char[N]){} will allocate a l-value
// with lifetime tied to the local block.
#define local_sprintf(N, ...) snprintf_assert((char[N]){}, N, __VA_ARGS__)

用途:

use_string(local_sprintf(256, format, ...));

我相信这是明确定义的,因为复合文字数组的生命周期将与封闭块相关联。有什么理由可以避免这种情况吗?

c c-strings c99
1个回答
0
投票

与在调用

snprintf_assert
之前简单定义本地数组相比,此技术存在一些缺点:

  • 定义固定大小的数组

    N
    可移植到不支持 VLA 和复合文字的 C++ 和 C 实现。

  • 复合文字

    (char[N]){}
    (您可以编写
    (char[N]){0}
    以便向后移植到 C99)定义但也初始化临时未命名数组,因此您会产生额外的
    memset()
    N
    字节到
    0
    。这可能不是一个很大的开销,除非您使
    N
    变大以容纳潜在的大型构造字符串。

© www.soinside.com 2019 - 2024. All rights reserved.