Я запускаю следующий код через разные компиляторы:
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, код компилируется без предупреждений.
void**
это не общий указатель. Только void*
есть.
(void**)
является явным приведением стиля c. Он говорит компилятору не смотреть внимательно на то, что вы делаете, и доверять вам. Это явное переопределение системы безопасности типов, и компиляторы должны принимать практически любые преобразования. Следует избегать бросков в стиле C, они слишком мощные. Используйте приведение C ++, например, static_cast
которое будет жаловаться, если вы пытаетесь сделать что-то, что не имеет смысла.