gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 12:20:25 29 4
gpt4 key购买 nike

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

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

据我所知, void **而不是通用指针,这意味着来自另一个指针的任何转换都不应编译或至少发出警告。但是,这是我的结果(全部在Windows上完成):
  • gcc -引发警告,如预期的那样。
  • g++ -引发错误,如预期的那样(这是由于C++的允许性较低,对吧?)
  • MSVC(cl.exe)-即使指定了/Wall,也不会引发任何警告。

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

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

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

    最佳答案

    Am I missing something about the whole thing and is there any specific reason why MSVC does not produce a warning? MSVC does produce a warning when converting from void ** to float **



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

    Another thing of note: If I replace a = b with the explicit conversion a = (void **)b, none of the compilers throw a warning. I thought this should be an invalid cast, so why wouldn't there be any warnings?



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

    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. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.



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

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

    ...

    Is this just sloppy work on NVIDIA's end or am I, again, missing something?



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

    关于c++ - 在不同的编译器上转换为void **,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59843989/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com