Я запускаю следующий код через разные компиляторы:
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которое будет жаловаться, если вы пытаетесь сделать что-то, что не имеет смысла.