std::nullptr_t 可变参数函数中的参数
std::nullptr_t arguments in variadic functions
因此,显然std::nullptr_t
参数在没有参数的情况下传递(通过 ...
(时会转换为类型 void *
(N3337 的 5.2.2/7 节(的空指针。这意味着,例如,要正确传递 null char *
指针,仍然需要强制转换:
some_variadic_function("a", "b", "c", (const char *( std::nullptr(;
因为不能保证空void *
与空char *
具有相同的位模式。正确?
这也意味着在这种情况下,除了可能为了清楚起见之外,std::nullptr
比0
没有任何优势。
你问:
因为不能保证空
void *
与空char *
具有相同的位模式。正确?
好吧,实际上,这种保证确实存在,重复数据删除器的答案已经显示了标准要求这一点的地方。但这与您的问题无关。
将void *
传递给可变参数函数,并使用va_arg
作为char *
访问它,作为特殊例外是特别允许的。
C++11:
18.10 其他运行时支持 [支持.运行时]
1 标头
<csetjmp>
(非局部跳转(、<csignal>
(信号处理(、<cstdalign>
(对齐(、<cstdarg>
(变量参数(、<cstdbool>
(__bool_true_false_are_defined
(。 (运行时环境getenv()
,system()
(和<ctime>
(系统时钟clock()
,time()
(提供了与C代码的进一步兼容性。2 这些标头的内容与标准 C 库标头
<setjmp.h>
、<signal.h>
、<stdalign.h>
、<stdarg.h>
、<stdbool.h>
、<stdlib.h>
和<time.h>
相同,如下所示 变化:[...没有关于
va_arg
]
C99:
7.15.1.1
va_arg
宏[...]如果没有实际的下一个参数,或者类型与实际下一个参数的类型不兼容(根据默认参数升级升级(,则行为是未定义的,但以下情况除外:
-- 一种类型是有符号整数类型,另一种类型是对应的无符号整数类型,该值在两种类型中都是可表示的;
-- 一种类型是指向 void 的指针,另一种是指向字符类型的指针。
但是,这确实意味着,在两种T1
和T2
具有相同表示和对齐要求的其他情况下,如果将T1
传递给可变参数函数,则行为是未定义的,并且将其作为T2
检索。
例如:允许传递(void *) 0
并按char *
访问它,也允许传递(void *) 0
并按unsigned char *
访问它,但不允许传递(char *) 0
并按unsigned char *
访问它。如果编译器能够内联对可变参数函数的调用,并根据标准的严格要求进行优化,则此类不匹配可能会严重中断。
这也意味着,在这种情况下,除了可能为了清楚起见之外,
std::nullptr
比0
没有任何优势。
我绝对不会在不强制转换的情况下使用nullptr
,即使在这种特殊情况下它是有效的。很难看出它是有效的。如果无论如何都包含强制转换,则(char *) 0
与空指针值一样清晰。
你错了。为数不多的保证之一是char*
具有与相应void*
相同的大小和表示形式。
3.9.2 化合物类型 §4
指向符合 cv 条件 (3.9.3( 或不符合 cv 条件的 void 的指针可用于指向未知类型的对象。 这样的指针应该能够容纳任何对象指针。cv
void*
类型的对象应具有相同的 作为简历char*
的表示和对齐要求。
编辑:看起来hvd的这个答案更好,显示了更多特定于问题的可变参数函数部分的陷阱。
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类