2010-05-05 34 views
8

Điều này có vẻ lạ, nhưng trong C (size_t) (void *) 0 == 0 không được đảm bảo bởi thông số ngôn ngữ. Các trình biên dịch được phép sử dụng bất kỳ giá trị nào chúng muốn cho null (mặc dù chúng hầu như luôn sử dụng 0.)Có sự khác biệt nào giữa null và 0 khi gán cho con trỏ trong mã không an toàn không?

Trong C#, bạn có thể gán null hoặc (T *) 0 cho con trỏ trong mã không an toàn.

  1. Có sự khác biệt nào không?
  2. (dài) (void *) 0 == 0 (đảm bảo hoặc không nói một cách khác: IntPtr.Zero.ToInt64() == 0)

MSDN có này để nói về IntPtr. Không:

"Giá trị của trường này không tương đương với giá trị rỗng". Vâng, nếu bạn muốn được tương thích với mã C, mà làm cho rất nhiều ý nghĩa - nó sẽ là vô giá trị cho interop nếu nó không chuyển đổi thành một con trỏ null C. Nhưng tôi muốn biết nếu IntPtr.Zero.ToInt64() == 0 có thể có, ngay cả khi IntPtr.Zero nội bộ là một số giá trị khác (CLR có thể hoặc không thể chuyển đổi null thành 0 trong hoạt động truyền)

Không phải là bản sao của this question

Trả lời

5

Bạn có thể tránh được vấn đề:

char* foo = (char*)(void*)0; 
char* bar = default(char*); // <======= the one to look at 
Console.WriteLine(foo == bar); // writes True 

Vì vậy, chúng giống nhau, nhưng sử dụng default tránh phải nhúng bất kỳ giả định hoặc giả mạo nào vào mã. Cách tháo rời ở trên, sự khác biệt chỉ được ký/unsigned - cả hai bắt đầu với một 4-byte liên tục (i4/u4) sau đó đúc để bản địa-int (i/u) (các // bình luận là của tôi):

.maxstack 2 
.locals init (
    [0] char* foo, 
    [1] char* bar) 
L_0000: ldc.i4.0 // (char*)(void*)0; 
L_0001: conv.i 
L_0002: stloc.0 // foo= 
L_0003: ldc.i4.0 // default(char*); 
L_0004: conv.u 
L_0005: stloc.1 // bar= 
L_0006: ldloc.0 
L_0007: ldloc.1 
L_0008: ceq // foo == bar 
L_000a: call void [mscorlib]System.Console::WriteLine(bool) 
+0

Ah yeh, tôi quên rằng mặc định hoạt động trên con trỏ. Đó là một giải pháp tốt đẹp. – Eloff

0

Trong C, NULL được định nghĩa là kiến ​​trúc cụ thể. Trong khi hầu hết các kiến ​​trúc sử dụng 0, một số thì không. Vì vậy, bạn không thể giả định rằng NULL == 0 trong C.

Không khá chắc chắn như thế nào nó hoạt động trong C# mặc dù tôi sẽ khuyên bạn nên dính vào cách chuẩn xác NULL trong C# thay vì đúc nó vào 0.

+0

Cách tiêu chuẩn xác định null cho con trỏ trong C# là gì? Tôi đã nhìn thấy cả hai được sử dụng, và đúc 0 có vẻ là phổ biến hơn. Tôi thích null vì nó dễ đọc hơn, nhưng quyết định sử dụng thực sự phụ thuộc vào câu trả lời cho dù chúng có tương đương hay không. – Eloff

Các vấn đề liên quan