指向void(void*
)的指针兼容并且可以保存任何其他指针类型。对于指向const void(const 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标准定义(和允许)吗?
答案 0 :(得分:2)
我会直接承认我很少在C中发现复合文字的需要,但你的语法肯定是有根据的。如果我正确地理解了你的问题,那就是试图确定应用于复合文字的上述address-of运算符是否会产生const
vs非const指针。
除非化合物本身是常量限定的,否则它是非常量的。我没有方便的C99标准,但我能为此提出的最好的例子就是:
C11标准§6.5.2.5p11
可以通过以下结构指定只读复合文字:
(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6}
结合以下对复合文字的存储资格的描述:
C11标准§6.5.2.5p5
复合文字的值是初始化列表初始化的未命名对象的值。如果复合文字出现在函数体外,则该对象具有静态存储持续时间;否则,它具有与封闭块相关的自动存储持续时间。
因此存储也存在(即它不驻留在某处的只读存储器中)。除非const
合格,否则复合文字实际上是非const的(如果复合文字数组或结构实际上可能具有自己的const
限定,则其中的数据/元素)。 / p>
从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*
}
考虑到所有这一切,我完全看似错误地理解了你的问题,如果这样,那么我可以澄清一下我的删除链接。
答案 1 :(得分:1)
此次通话没有问题
SomeFunc( &( int ){ 12345 } ) ;
C标准中有一个类似的例子
drawline(&(struct point){.x=1, .y=1},
&(struct point){.x=3, .y=4});
根据C标准(6.5.2.2函数调用)
7如果表示被调用函数的表达式具有类型 确实包含一个原型,参数被隐式转换为 如果通过赋值,对相应参数的类型,采取 每个参数的类型是其不合格的版本 声明的类型。
C标准相对于转化似乎存在差距。 C ++标准
中描述了更详细的隐式转换1标准转化是具有内置含义的隐式转化。第4条列举了全套此类转换。标准转换序列是按以下顺序的一系列标准转换:
- 来自以下集合的零或一次转换:左值到右值的转换,数组到指针的转换以及函数到指针的转换。
- 来自以下设置的零次或一次转换:整数促销,浮点促销,积分转换,浮点转换,浮点积分转换,指针转换,指向成员转换的指针以及布尔转换。
- 零或一个资格转换。
因此可以看出,标准转换序列包括一个指针转换和一个限定转换。
C标准可以给出类似的详细描述。