void*总是与char*具有相同的表示吗?

PSk*_*cik 24 c pointers language-lawyer

将一个void*总是有相同的表示为char*

细节:

我想使用一个可变参数函数,它使char*被(char*)0类似的终止:

int variadic(char*, ...); //<-prototype
variadic("foo", "bar", (char*)0); //<- usage
Run Code Online (Sandbox Code Playgroud)

我想,以取代(char*)0NULL,但是从判断 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf的:

66)宏NULL在(和其他头部)中定义为空指针常量; 见7.19.

3值为0的整型常量表达式或类型为void*的表达式称为空指针常量.66)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.

我不能,因为在variadic上下文中,我绝对需要char*一个平原0是不可接受的.

如果我定义:

#define NIL (void*)0 /*<= never a plain 0*/
Run Code Online (Sandbox Code Playgroud)

用它来终止我是合法的variadic(char*,...)吗?

usr*_*usr 35

C11,§6.2.5,28(草案N1570)说:

指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求.48)类似地,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求.

(强调我的).

  • @ poizan42我认为函数指针和数据指针在C中被区别对待,明确地处理你提到的情况,其中代码指针更大. (3认同)
  • 这实际上是一个有趣的要求.因此,在代码指针大于数据指针指针的体系结构中,此要求会强制填充char指针.Intel 80C51就是这样一个例子,因为它有128字节的ram但是4 KB的程序rom.(虽然这是一个改进的哈佛架构,它允许将程序rom作为数据读取,因此统一数据指针仍需要更多空间) (2认同)
  • 请注意,这不足以允许`void*`作为无类型参数*传递*,其中被调用者期望`char*`,反之亦然.(根据MSalters的回答,在'va_arg`的定义中有额外的规则可以缩小差距.)这不是*在C90中的要求. (2认同)
  • @dan04:这仅适用于可通过`dlsym()` 获得的函数指针。原则上,其他函数指针值可能无法无损地转换为 `void*`。 (2认同)

MSa*_*ers 10

它特别允许使用void*参数va_arg(args, char*),反之亦然,而不仅仅是空指针.

另见http://en.cppreference.com/w/cpp/utility/variadic/va_arg