在不同的编译器上转换为void **


9

我一直在通过不同的编译器运行以下代码:

int main()
{
    float **a;
    void **b;
    b = a;
}

从我已经能够收集,void **不是一个普通的指针,这意味着从另一个指针任何转换不应该编译或至少抛出一个警告。但是,这是我的结果(全部在Windows上完成):

  • gcc-如预期的那样发出警告。
  • g ++ -引发错误,如预期的那样(这是由于C ++的宽松输入造成的,对吧?)
  • MSVC(cl.exe) -即使指定了/ Wall,也不会引发任何警告。

我的问题是:我是否遗漏了全部内容?是否有任何特定原因导致MSVC无法发出警告?MSVC 转换时产生警告 void **float **

还要注意的另一件事:如果我将其替换a = b为显式转换a = (void **)b,则所有编译器都不会发出警告。我认为这应该是无效的演员表,所以为什么不会有任何警告?

我问这个问题的原因是因为我开始学习CUDA并在官方编程指南(https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory)中学习可以找到以下代码:

// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);

应该执行对void **for 的隐式转换&d_A,因为的第一个参数cudaMalloc是类型void **。在整个文档中都可以找到类似的代码。这只是NVIDIA的草率工作,还是我又错过了什么?由于nvcc使用MSVC,因此代码编译时不会发出警告。


3
发布的3个直播中的错误:godbolt.org/z/GQWMNo
理查德·克里滕

3
MSVC对我来说是代码错误。您正在使用哪个版本?但是可以,void**不是通用指针。只有void*
NathanOliver

感谢你及时的答复!x64的19.24.28315显然是?我以前没有真正使用过MSVC。
CaptainProton42

2
(void**)是显式的c样式强制转换。它告诉编译器不要仔细观察您的工作并信任您。它是对类型安全系统的显式覆盖,并且要求编译器基本上接受任何类型的转换。应该避免C样式转换,因为它们太强大了。使用C ++强制转换,例如static_cast,如果您尝试做没有意义的操作,将会抱怨。
弗朗索瓦·安德列

@RichardCritten错误语言-没有错误godbolt.org/z/RmFpgN C ++ cuda通常需要显式强制转换。
P__J__

Answers:


4

我是否在整个事情上都遗漏了什么?MSVC不发出警告有任何特定原因吗?从void **转换为float **时,MSVC会产生警告

这种不进行强制转换的分配违反了约束,因此符合标准的编译器将打印警告或错误。但是,MSVC不是完全符合C的实现。

注意的另一件事:如果我用显式转换a =(void **)b替换a = b,则所有编译器都不会发出警告。我以为这应该是无效的演员,所以为什么不会有任何警告?

在某些情况下,允许通过强制转换进行指针转换。C标准在6.3.2.3p7节中指出以下内容:

指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针未针对引用类型正确对齐,则该行为未定义。否则,当再次转换回时,结果应等于原始指针。当指向对象的指针转换为字符类型的指针时,结果指向该对象的最低寻址字节。结果的连续递增(直到对象的大小)会产生指向对象剩余字节的指针。

因此,您可以在没有对齐问题的情况下在指针类型之间进行转换,而只能转换回去(除非目标是char *)。

float* d_A;
cudaMalloc(&d_A, size);

...

这只是NVIDIA的草率工作,还是我又错过了什么?

大概,此函数正在取消引用给定的指针并写入一些已分配内存的地址。这意味着它将试图float *像写入一样写入void *。这与到/从的典型转换不同void *。严格来说,这看起来似乎是未定义的行为,尽管它“起作用”,因为现代x86处理器(不在实模式下)对所有指针类型都使用相同的表示形式。


@dbush非常有用,谢谢!我知道为什么它可以工作。仍然,大多数编译器是否会因为&d_A没有所需的类型而引发警告甚至错误?
CaptainProton42

3
注意如何解释,如果使用C ++编译器编译CUDA,可能会存在模板技巧
talonmies
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.