2015-02-06 4 views
13

Я искал спецификацию языка C#, и я не могу найти ничего, что говорит о том, что тип указателя (например, int*) инициализируется значением по умолчанию. Я создал простое тестовое приложение и, похоже, инициализирует их до нуля, но я хотел бы подтвердить это с помощью спецификации.C# значение по умолчанию для типа указателя

я начал искать это, потому что я заметил в отражателе IntPtr класса использует этот код, чтобы определить его IntPtr.Zero:

public struct IntPtr : ISerializable 
{ 
    private unsafe void* m_value; 
    public static readonly IntPtr Zero; 

    ....... 

    public static unsafe bool operator ==(IntPtr value1, IntPtr value2) 
    { 
     return (value1.m_value == value2.m_value); 
    } 

    ........ 
} 

означает, что если сравнивать с IntPtr.Zero он на самом деле является сравнением от значения по умолчанию, назначенном поле m_value, которое имеет тип void*.

Спасибо.

+1

Есть части спецификации, обсуждающие указатели, в которых обсуждается, как они взаимодействуют с определенным анализом присваивания. Учитывая, что вся точка определенного анализа присваивания заключается в том, чтобы избежать вас, наблюдая неинициализированное состояние переменной, возможно, ответ Му. Кроме того, не все, что вы видите в реализации типов фреймворков, - это полная история - иногда специальная обработка по времени выполнения приводит к фактическому поведению. –

+0

Хорошо заметили ... похоже, что они пропустили это при написании спецификации. Угадайте, что вы можете предположить, что это ноль (null) :-) – buffjape

+0

Смущает то, что CIL определяет типы указателей как подмножество ссылочных типов, но C# определяет типы указателей как отдельный класс типов. Поэтому, когда CIL указывает, что ссылочные типы имеют значение по умолчанию «null», это означает больше, чем когда C# указывает то же самое. – hvd

ответ

-1

С помощью отладчика Visual Studio вы можете получить значение по умолчанию, присвоенное указателю int. В 32-битной архитектуре это 0x00000000 (32 0 бит).

class Program 
{ 
    private static unsafe int* m_value; 
    static void Main(string[] args) 
    { 
    } // <<== Break point here 
} 

Watch Window 
_____________________________________________ 
Name Value  Type 
======= ========== ======== 
m_value 0x00000000 int* 
+2

Да, как я уже сказал, я написал тестовое приложение, которое это сделало, но это не обязательно означает, что значение всегда будет равным нулю (это может быть просто удача). – user3784392

+3

Спецификация C# очень тщательно не определяет значение defualt для указателя. – Rawling

1

Я считаю, что указатели не имеют значения по умолчанию; из-за значения указателя, являющегося адресом части памяти, содержащей то, на что вы ее назначили. Если вы его не назначили, это может указывать на что-либо в памяти.

Возможно, поведение CLR по умолчанию заключается в том, чтобы установить его в IntPtr.Zero, который «представляет указатель или дескриптор, который был инициализирован до нуля», что, скорее всего, будет связано с ответом Кармело Флоридии. Это, по-видимому, деталь реализации, о которой спецификация не может быть подробно рассмотрена.

1

Значение по умолчанию для указателей по спецификациям: null. Это вытекает из двух фактов.

Первым фактом является то, что указатель ссылочный тип. Это описано в ECMA-335: enter image description here

Второй факт заключается в том, что reference-type has default value - null.

+0

'Type.IsClass' на указателях является' true', но 'default (typeof (void *))' is 'IntPtr.Zero', а не null. Либо ссылочные типы не имеют значения по умолчанию как «null» * always *, либо указатель не является ссылочным типом. Я считаю, что это первый. – nawfal

+0

@nawfal 'IntPtr.Zero' инициализируется по умолчанию. Первое поле 'IntPtr.Zero' является' private unsafe void * m_value'. Если 'void * m_value' является' IntPtr.Zero', то мы имеем сходство рекурсии. –

Смежные вопросы