Я використовував наступний код через різні компілятори:
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 **
для &d_A
, як перший аргумент cudaMalloc
типу void **
. Подібний код можна знайти у всій документації. Це просто неохайна робота з кінця NVIDIA чи я, знову ж, щось пропускаю? Оскільки nvcc
використовується MSVC, код компілюється без попереджень.
void**
це не загальний покажчик. Тільки void*
є.
(void**)
це чіткий склад стилю c. Це заказує компілятору не дивитися уважно на те, що ви робите, і не довіряти вам. Це явне перевищення системи безпеки типу, і компілятори зобов'язані прийняти в основному будь-який вид перетворення. Слід уникати ролі в стилі C, вони занадто потужні. Використовуйте C ++ ролики, на зразок static_cast
яких скаржиться, якщо ви намагаєтесь зробити щось, що не має сенсу.