这有什么错铸像(无效**)及device_array? [英] What's wrong with casting like (void**)&device_array?

查看:112
本文介绍了这有什么错铸像(无效**)及device_array?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于使用 cudaMalloc((无效的另外一个问题这个答案 ** )及device_array,NUM_BYTES),它使用无效** 作为输出参数,而不是通过一个无效* 像标准的返回值的malloc

There is this answer on another question about the use of cudaMalloc((void**)&device_array, num_bytes), which uses void** as output argument instead of passing a void* as return value like the standard malloc.

它批评NVIDIA的API,并指出:

It criticizes NVIDIA's API and states :

铸造,如(无效**)及device_array,是无效的C和结果
  未定义的行为。

Casting, as in (void**)&device_array, is invalid C and results in undefined behavior.

,并已upvoted几次(8截至目前),所以我认为有一定的道理在里面。

and has been upvoted several times (8 as of now), so I assume there is some truth in it.

我不明白这有什么错铸那里。

I don't understand what's wrong with casting there.


  • 什么是无效这儿用?

  • 在什么情况下会这导致不确定的行为?

我所知道的是,它编译没有警告,与我预期的行为运行。但我不掌握相关C到标准规范的水平。

All I know is that it compiles without warning and runs with the intended behavior for me. But I am not knowledgeable with C up to standard specification level.

推荐答案

的问题是,无效* 有一个在C特殊的含义,具有特殊的规则(1)。它是唯一指针类型/从中你可以安全地将任何其他指针类型。然而,这些特殊规则不递归适用无效**

The problem is that void* has a special meaning in C, with special rules (1). It is the only pointer type to/from which you can safely convert any other pointer type. However, these special rules do not apply recursively to void**.

意思就是说code像为int * PTR =的malloc(X); 是完全没有问题的,但

Meaning that code like int* ptr = malloc(x); is perfectly fine, but

int* ptr; 
cudaMalloc(&ptr, x); // bad

不精!从 INT ** A指针转换为无效** 是不明确。理论上,这可能会导致不确定的行为和不对(2)。

is not fine! A pointer conversion from int** to void** is not well-defined. In theory this could cause undefined behavior and misalignment (2).

在另外,也可能是与指针锯齿问题。编译器是免费的假设的无效** 从未通过 INT访问** 和内容可以因此,优化以意想不到的方式在code,导致对违反严格别名规则(6.5)的未定义的行为。

In addition, there might also be problems with pointer aliasing. The compiler is free to assume that the contents of a void** is never accessed through a int** and could therefore optimize the code in unexpected ways, leading to undefined behavior for violation of the strict aliasing rule (6.5).

这意味着你将不得不写code这样才能安全地使用功能:

Which means you will have to write code like this in order to safely use the function:

void* vptr; 
int*  iptr;

cudaMalloc(&vptr, x);
iptr = vptr;


(1)C11 6.3.2.3/1:


(1) C11 6.3.2.3/1:

要无效的指针可被转换成或从一个指针到任何物体
  类型。的指针的任何对象类型可被转换成一个指针
  作废,然后再返回;结果应比较等于原
  指针。

A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

(2)C11 6.3.2.3/7:

(2) C11 6.3.2.3/7:

一个指针对象类型可被转换成一个指针
  不同的对象类型。如果所得到的指针不正确
  为引用类型一致,行为是不确定的。

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.

这篇关于这有什么错铸像(无效**)及device_array?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆