是否有安全的方法来断言字符串视图是否以 null 终止?
Is there a safe way to assert if a string view is null terminated?
我的代码中有一部分广泛使用了字符串视图。在任何地方都使用 std::string
是不可想象的,并且 char const*
将无法工作,因为存在关联容器、许多比较以及难以使用普通原始字符串进行的此类操作。
但是,有一个地方最终会处理一个C API,它需要空终止字符串:
auto sv = std::string_view{/* ... */};
c_api(sv.data());
虽然这在我的情况下工作正常,但我想确保一切正常并断言字符串以 null 终止,因为我的系统构建字符串视图并将其发送到那里不会使用子字符串视图,并且将从字符串文字或 std::string
生成它们。我知道我会没事的。
然而,另一个程序员可能不知道所有这些,并尝试在字符串视图上使用 substr
,或发送非空终止字符串。非空终止字符串是不好的,因为它会导致未定义的行为,但字符串视图中的子字符串更糟,因为发送到 C API 时不会应用上限,并且不会出现未定义的行为被调用,但会引入一个非常难以发现的具有意外行为的错误。
所以我想使用断言来传达这一点:
auto sv = std::string_view{/* ... */};
assert(*(sv.data() + sv.length()) == '[=11=]'); // Yay?
c_api(sv.data());
但我发现它不完整且容易出错,因为它可能会读取空终止字符串的边界。
有没有办法安全地断言字符串视图确实以 null 终止?
这可能会很痛苦,但我会编写自己的 string_view
保证以 null 终止。
因为 string_view
可以构造成
char array[3] = {'B', 'a', 'r'};
std::string_view array_v(array, sizeof array);
测试
*(sv.data() + sv.length()) == '[=11=]'
在这种情况下是未定义的行为,因为最后一个有效索引是 2
但您访问 3
。 std::string_view
需要公开它不知道的信息才能让你这样做,因为它不能,你不能可靠地知道。
我的代码中有一部分广泛使用了字符串视图。在任何地方都使用 std::string
是不可想象的,并且 char const*
将无法工作,因为存在关联容器、许多比较以及难以使用普通原始字符串进行的此类操作。
但是,有一个地方最终会处理一个C API,它需要空终止字符串:
auto sv = std::string_view{/* ... */};
c_api(sv.data());
虽然这在我的情况下工作正常,但我想确保一切正常并断言字符串以 null 终止,因为我的系统构建字符串视图并将其发送到那里不会使用子字符串视图,并且将从字符串文字或 std::string
生成它们。我知道我会没事的。
然而,另一个程序员可能不知道所有这些,并尝试在字符串视图上使用 substr
,或发送非空终止字符串。非空终止字符串是不好的,因为它会导致未定义的行为,但字符串视图中的子字符串更糟,因为发送到 C API 时不会应用上限,并且不会出现未定义的行为被调用,但会引入一个非常难以发现的具有意外行为的错误。
所以我想使用断言来传达这一点:
auto sv = std::string_view{/* ... */};
assert(*(sv.data() + sv.length()) == '[=11=]'); // Yay?
c_api(sv.data());
但我发现它不完整且容易出错,因为它可能会读取空终止字符串的边界。
有没有办法安全地断言字符串视图确实以 null 终止?
这可能会很痛苦,但我会编写自己的 string_view
保证以 null 终止。
因为 string_view
可以构造成
char array[3] = {'B', 'a', 'r'};
std::string_view array_v(array, sizeof array);
测试
*(sv.data() + sv.length()) == '[=11=]'
在这种情况下是未定义的行为,因为最后一个有效索引是 2
但您访问 3
。 std::string_view
需要公开它不知道的信息才能让你这样做,因为它不能,你不能可靠地知道。