2014-10-07 137 views
-1

指向void(void*)的指针与任何其他指针类型兼容,并且可以容纳任何其他指针类型。对于指向const void的指针也是如此(const void*)。使用const void *而不是void *,对于任何类型

时间:

6.3.2.3,P2:对于任何限定符Q,一个指针指向一个非Q限定的类型可以被转换为一个指向 类型的q合格版本;存储在原始值和转换后的指针 中的值应相等。

因为我允许这样的:

int n = 0 ; 
void* p = &n ; 

我应该也被允许这样的:

int n = 0 ; 
const void* p = &n ; 

这使我想起我的最后一点,这是这一切也应举行用于复合文字。

void SomeFunc(const void* p) { printf("%p",p) } ; 

SomeFunc(&(int){ 12345 }) ; 

应由C标准定义(并允许)?

回答

2

我会直接承认我很少在C语言中找到对复合文字的需求,但是您的语法绝对是有根据的。如果我正确理解你的问题,那么试图确定前面提到的应用于复合文字的地址运算符是否导致const vs非const指针。

它是非const的,除非化合物本身是const限定的。我没有C99标准得心应手,但我可以强加于我们的最佳例子是在启发性的例子:

C11标准§6.5.2.5P11

只读复合文字再加上从复合文字的存储资格的描述

(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6} 

可以通过像构造来指定点

C11标准§6.5.2.5P5

的化合物的值字面是,由初始化列表初始化未命名的对象的。如果复合文字出现在函数主体之外,则该对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储持续时间。

所以存储也是存在的(即它不在某处的只读存储器中)。除非const限定,否则复合文字实际上是非常量(如果复合文字数组或结构实际上可能具有其自己的const限定条件,则其中的数据/元素为非const)。

Type *要么void*const void*翻译的机制是有希望明显,但它是值得您的样品的一些扭转指出:

void SomeFunc(void* p) { printf("%p\n",p); } ; 
void SomeFuncConst(const void* p) { printf("%p\n",p); } ; 

int main() 
{ 
    SomeFunc(&(int){ 12345 }) ;  // OK. int* to void* 
    SomeFuncConst(&(int){ 12345 }) ; // OK. int* to const void* 
    SomeFuncConst &(const int){12345}); // OK. const int* to const void* 
    SomeFunc(&(const int){ 12345 }) ; // ERROR. const int* not allowed as void* 
} 

鉴于所有这一切,这是完全可行的,我误解你的问题,并且如果这样的话,请善意澄清我达到的删除链接。

+0

是的,我错过了你有两个功能。 – 2501 2014-10-07 16:33:46

+0

是的,我的问题是从类型*和const类型*转换为const void *。 – 2501 2014-10-07 16:34:17

+0

我想我必须相信你const int * const void *。 – 2501 2014-10-07 16:37:16

1

没有与此呼叫

SomeFunc(&(int){ 12345 }) ; 

一个类似的例子有在C标准

drawline(&(struct point){.x=1, .y=1}, 
     &(struct point){.x=3, .y=4}); 

按照C标准没有问题(6.5.2.2函数调用)

7如果表示被调用函数的表达式的类型为 的确包含原型,则argume如果通过赋值将nts作为 隐式转换为相应参数的类型,则将 的每个参数的类型作为其 声明类型的非限定版本。

看来C标准与转换相比存在差距。在C++标准中描述了更详细的隐式转换。

1标准转换是具有内置含义的隐式转换。第4条列举了一整套此类转换。标准转换序列是以下列顺序的标准转换序列:

- 从以下集合中进行零或一次转换:左值到右值转换,数组到指针转换以及函数至指针转换。

- 零或者选自以下组的一个转换:积分促销,浮点推广,积分转换,浮点转换,浮积分转换,指针转换,指针构件转换,和布尔转换。

- 零或一个合格转换。

因此,因为它被认为是标准的转换序列包括一个指针转换和和一个资格转换。

C标准可以给出类似的详细描述。

+0

什么是drawline的原型。它是否需要const void *? – 2501 2014-10-07 15:55:12

+0

@ 2501从示例中可以看出,functopn接受两个指向结构点的指针。不过,任何指针都可以隐式转换为void指针。所以const void *没有问题。 – 2014-10-07 16:00:18

+0

你的最后一个陈述不符合逻辑前者。你能否详细说明答案? – 2501 2014-10-07 16:01:55

相关问题