Saya telah menjalankan kode berikut melalui berbagai kompiler:
int main()
{
float **a;
void **b;
b = a;
}
Dari apa yang saya sudah mampu mengumpulkan, void **
adalah tidak pointer generik yang berarti bahwa setiap konversi dari pointer lain tidak harus mengkompilasi atau setidaknya melempar peringatan. Namun, inilah hasil saya (semua dilakukan pada Windows):
- gcc - Melempar peringatan, seperti yang diharapkan.
- g ++ - Melempar kesalahan, seperti yang diharapkan (ini disebabkan oleh pengetikan C ++ yang kurang permisif, kan?)
- MSVC (cl.exe) - Melemparkan tidak ada peringatan sama sekali, bahkan dengan / Wall ditentukan.
Pertanyaan saya adalah: Apakah saya kehilangan sesuatu tentang semuanya dan apakah ada alasan khusus mengapa MSVC tidak menghasilkan peringatan? MSVC memang menghasilkan peringatan saat mengkonversi dari void **
menjadi float **
.
Catatan lain: Jika saya mengganti a = b
dengan konversi eksplisit a = (void **)b
, tidak ada kompiler yang memberikan peringatan. Saya pikir ini harus menjadi pemain yang tidak valid, jadi mengapa tidak ada peringatan?
Alasan saya mengajukan pertanyaan ini adalah karena saya mulai mempelajari CUDA dan dalam Panduan Pemrograman resmi ( https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory ) kode berikut dapat ditemukan:
// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);
yang harus melakukan konversi implisit ke void **
untuk &d_A
, karena argumen pertama cudaMalloc
adalah tipe void **
. Kode serupa dapat ditemukan di seluruh dokumentasi. Apakah ini hanya pekerjaan ceroboh di ujung NVIDIA atau apakah saya, sekali lagi, melewatkan sesuatu? Karena nvcc
menggunakan MSVC, kode ini dikompilasi tanpa peringatan.
void**
bukan penunjuk generik. Hanya void*
itu.
(void**)
adalah pemeran gaya c eksplisit. Ia memberi tahu kompiler untuk tidak melihat dengan cermat apa yang Anda lakukan dan memercayai Anda. Ini merupakan override eksplisit dari sistem keselamatan jenis dan kompiler diharuskan untuk menerima konversi apa pun pada dasarnya. Pemain gaya C harus dihindari, mereka terlalu kuat. Gunakan C ++ gips seperti static_cast
yang akan mengeluh jika Anda mencoba melakukan sesuatu yang tidak masuk akal.