Farklı derleyiciler aracılığıyla aşağıdaki kodu çalıştırıyorum:
int main()
{
float **a;
void **b;
b = a;
}
Ben toplamak mümkün kadarıyla, void **
bir değil başka pointer herhangi dönüşüm derlemek ya da en azından bir uyarı atmak gerektiğini araçlarının genel bir işaretçi. Ancak, işte benim sonuçlarım (tümü Windows üzerinde yapılır):
- gcc - Beklendiği gibi bir uyarı atar.
- g ++ - Beklendiği gibi bir hata atar (bunun nedeni C ++ 'ın daha az izin veren yazımıdır, değil mi?)
- MSVC (cl.exe) - / Wall belirtilse bile hiçbir uyarı alamaz.
Sorum şu: Her şey hakkında bir şey eksik mi ve MSVC'nin bir uyarı vermemesinin belirli bir nedeni var mı? Msvc yapar dönüştürürken bir uyarı üretmek arasından void **
için float **
.
Başka bir şey: a = b
Açık dönüşümle değiştirirsem a = (void **)b
, derleyicilerin hiçbiri uyarı vermez. Bunun geçersiz bir oyuncu olması gerektiğini düşündüm, bu yüzden neden bir uyarı olmaz?
Bu soruyu sormamın nedeni, CUDA öğrenmeye başlamam ve resmi Programlama Kılavuzunda ( https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory ) aşağıdaki kod bulunabilir:
// Allocate vectors in device memory
float* d_A;
cudaMalloc(&d_A, size);
ilk argümanı tür olduğundan, void **
for için örtük bir dönüşüm gerçekleştirmelidir . Benzer kod belgelerin her yerinde bulunabilir. Bu NVIDIA'nın sonundaki özensiz bir iş mi yoksa yine bir şey mi kaçırıyorum? Yana kullanır MSVC, kod uyarıları olmadan derler.&d_A
cudaMalloc
void **
nvcc
void**
genel bir işaretçi değil. Sadece void*
.
(void**)
açık bir c tarzı oyuncu. Derleyiciye ne yaptığınıza yakından bakmamasını ve size güvenmesini söyler. Tip güvenlik sisteminin açık bir şekilde geçersiz kılınması ve derleyicilerin temelde her türlü dönüşümü kabul etmesi gerekir. C tarzı atmalardan kaçınılmalıdır, çok güçlüdürler. static_cast
Mantıklı olmayan bir şey yapmaya çalışıyorsanız şikayet edecek gibi C ++ dökümleri kullanın .