О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 00:59
Оценка: 18 (2)
Что-то я не въеду в принципы по которым компилятор должен отличать nullable-тип и оператор "? :".
Например:
int i = 0;
Console.WriteLine(i is int?);
Console.WriteLine(i is int? "+" : "-");

Надо заглядывать вперед анализируя наличие ":"? Или есть более простая эвристика?

Плюс смущает, что "i is int?" вообще компилируется. Ведь i имеет тип int, а не int?. Это случаем не баг?
Какой раздел спецификации описывает это дело?
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: О nullable-типах и операторе "? :"
От: Воронков Василий Россия  
Дата: 14.01.06 01:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Плюс смущает, что "i is int?" вообще компилируется. Ведь i имеет тип int, а не int?. Это случаем не баг?

VD>Какой раздел спецификации описывает это дело?

Ну так раз i is int? вообще не компилируется, значит тут никакой неоднозначности нет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 01:36
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ну так раз i is int? вообще не компилируется, значит тут никакой неоднозначности нет.


Я привел полностью компилируемый код.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: О nullable-типах и операторе "? :"
От: Воронков Василий Россия  
Дата: 14.01.06 01:54
Оценка:
Здравствуйте, VladD2, Вы писали:

ВВ>>Ну так раз i is int? вообще не компилируется, значит тут никакой неоднозначности нет.

VD>Я привел полностью компилируемый код.

Да, пардон. Что-то у меня уже от недосыпа в глаза двоится.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: О nullable-типах и операторе "? :"
От: Воронков Василий Россия  
Дата: 14.01.06 02:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что-то я не въеду в принципы по которым компилятор должен отличать nullable-тип и оператор "? :".

VD>Например:
VD>
VD>int i = 0;
VD>Console.WriteLine(i is int?);
VD>Console.WriteLine(i is int? "+" : "-");

VD>Надо заглядывать вперед анализируя наличие ":"? Или есть более простая эвристика?

А если наоборот — проверять является ли выражение проверкой типа? Т.е. не так уж и много вариантов завершения проверки i is int? — ";", ")", "]", "?"... Просто касательно провреки на наличие ":" мне не очень понятно ( по кр. мере сейчас ). Ведь между "?" и ":" может быть километр кода.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: О nullable-типах и операторе "? :"
От: Алексей.  
Дата: 14.01.06 09:45
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что-то я не въеду в принципы по которым компилятор должен отличать nullable-тип и оператор "? :".

VD>Например:
VD>
VD>int i = 0;
VD>Console.WriteLine(i is int?);
VD>Console.WriteLine(i is int? "+" : "-");

VD>Надо заглядывать вперед анализируя наличие ":"? Или есть более простая эвристика?

VD>Плюс смущает, что "i is int?" вообще компилируется. Ведь i имеет тип int, а не int?. Это случаем не баг?

VD>Какой раздел спецификации описывает это дело?

Это самая плохо специфицированная часть стандарта C#. Стандарт по этому поводу ничего не говорит.
Можно вычислить FIRST(expression) и FOLLOW(expression) и проанализировать первый токен после '?'.
токены FIRST(expression) будут соответствовать выражению
токены FOLLOW(expression) будут соответствовать типу
Re[2]: О nullable-типах и операторе "? :"
От: Алексей.  
Дата: 14.01.06 09:52
Оценка: 30 (1)
Подобные примеры не специфицированы потому что при их разборе не возникает неоднозначностей. Да, надо проводить чуть более сложный анализ, но разбор корректного выражения синтаксически всегда однозначен.
Re: О nullable-типах и операторе "? :"
От: Alexander__S  
Дата: 14.01.06 10:47
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Плюс смущает, что "i is int?" вообще компилируется. Ведь i имеет тип int, а не int?. Это случаем не баг?


Так же, как компилируется i is object, i is SomeType и проч. зачем тогда вообще нужен is? Я понимаю, четыре часа ночи...
Re: О nullable-типах и операторе "? :"
От: RoloTomasi Смерть хохлопидарам.
Дата: 14.01.06 11:26
Оценка:
Здравствуйте, VladD2, Вы писали:

Ладно компилируется почему true получаем?


    class tint<T> where T: struct{};
    static void Main()
    {
            int i = 0;
            Console.WriteLine(i is int?);
            Console.WriteLine(i is tint<int>); // а тут false
            Console.WriteLine(i is int? "+" : "-");
      new Program();
    }
Смерть хохлопидарам!
Re[2]: О nullable-типах и операторе "? :"
От: mormat Украина mormat.org.ua
Дата: 14.01.06 12:54
Оценка:
Здравствуйте, Alexander__S, Вы писали:

A__>Здравствуйте, VladD2, Вы писали:


VD>>Плюс смущает, что "i is int?" вообще компилируется. Ведь i имеет тип int, а не int?. Это случаем не баг?


A__>Так же, как компилируется i is object, i is SomeType и проч. зачем тогда вообще нужен is? Я понимаю, четыре часа ночи...


VladD2 хотел сказать, что если
            int i;
            Console.Write( i is int? );

или
            int? i;
            Console.Write( i is int );

то в обоих случаях на экран вылезет true. И это действительно странно, ибо
public struct Nullable<T> where T : struct

вряд ли должно соответствовать типу T.

Провёл пару экспериментов, -> пришёл к выводу, что тип Nullable в самом деле выделен на уровне языка.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусто
Re[2]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 13:17
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А если наоборот — проверять является ли выражение проверкой типа? Т.е. не так уж и много вариантов завершения проверки i is int? — ";", ")", "]", "?"...


О том и речь. Но хотелось бы иметь четкий алгоритм, а не придумывать собственные эвристики.

ВВ>Просто касательно провреки на наличие ":" мне не очень понятно ( по кр. мере сейчас ). Ведь между "?" и ":" может быть километр кода.


О том и речь. Нужно будет вручную (для гребаного CocoR) распознать любое выражение . Но есть нужен или пасрер LL(*), или много ручного траха.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 13:17
Оценка:
Здравствуйте, Алексей., Вы писали:

А>Подобные примеры не специфицированы потому что при их разборе не возникает неоднозначностей. Да, надо проводить чуть более сложный анализ, но разбор корректного выражения синтаксически всегда однозначен.


Однозначен то он однозначен. Но это же требует LL(*)-парсера.
Мне нужно азрулить ситуацию на CocoR который строит только LL(1)-парсеры с возможностью ручного заглядывания вперед (хоть до посинения).

Так вот у меня есть варианты:
1. Попытаться распознать выражение идущее за "?". Если выражение распознается и за ним идет ":" мы имеем дело с оператором "?:" и дело в шляпе. Если нет, то принимаем решение, что "?" — это часть определения типа.
Так вот проблема в том, что ручной анализ выражения — это застрелиться .
2. Придумать некую эвристику (наподобии той, что применяется для разруливания неоднозначностей с "F(G<A, B>(7));".

В общем, первый способ конечно надежен, но сложен и медленнен.
Между тем, описанная неоднозначность возникает только в случае применения оператора "is" в сочетании с нулбл-типами и/или оператором "?:".

Вот и хотелось бы попытаться определить эвристику по которой можно было бы ограничиться проверкой некоторого набора лексем.

Ведь если пойти логически, то если после "?" следуют: ")", "=", "?" (возможно что-то еще), то "?" точно являетс частью определения типа.

Вот и хотелось бы попытаться продумать набор таких предположений и проверить не возникает ли при этом каких-то проблем.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 13:17
Оценка:
Здравствуйте, RoloTomasi, Вы писали:

RT>Ладно компилируется почему true получаем?


Более корректный тест будет выглядеть так:
using System;

class Test<T> where T: struct
{
    public Test(T t) { _t = t; }
    T _t;
    public static implicit operator T(Test<T> test) { return test._t; }
};

class Program
{
    static void Main()
    {
        int i = 0;
        Console.WriteLine(i is int);
        Console.WriteLine(i is Test<int>); // а тут false
        Console.WriteLine(i is int?);
        Console.WriteLine(i is int? "+" : "-");
        Console.WriteLine(i is int ? ?"+" : "-");
    }
}


но все равно получается false. Так что поддержка нулбл-типов явно встроена в язык по самые помидоры. Или это ошибка компилятора.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: О nullable-типах и операторе "? :"
От: Alexander__S  
Дата: 14.01.06 13:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>но все равно получается false. Так что поддержка нулбл-типов явно встроена в язык по самые помидоры. Или это ошибка компилятора.


Извините за настырность, но опять-таки, почему компилятора? Может быть, все-таки CLR в рантайме во время выполнения оператора is проверяет, является ли тип Nullable, инстанцированным данным типом?
Re[4]: Дополнение
От: Alexander__S  
Дата: 14.01.06 14:32
Оценка:
Хотя поддержка со стороны компилятора действительно есть.
Вообще, здесь доволно подробно описано:
http://msdn2.microsoft.com/en-us/library/2cf62fcy.aspx
Re[3]: О nullable-типах и операторе "? :"
От: mihailik Украина  
Дата: 14.01.06 14:33
Оценка:
VD> Так что поддержка нулбл-типов явно встроена в язык по самые помидоры.

Ну она даже в CLR встроена, что уж там про компилятор говорить.
Re[4]: О nullable-типах и операторе "? :"
От: Alexander__S  
Дата: 14.01.06 15:10
Оценка:
Или, может быть, имелся в виду JIT-компилятор, который генерирует неправильный код для isinst?
Re[4]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 15:54
Оценка: +1
Здравствуйте, Alexander__S, Вы писали:

A__>Извините за настырность, но опять-таки, почему компилятора? Может быть, все-таки CLR в рантайме во время выполнения оператора is проверяет, является ли тип Nullable, инстанцированным данным типом?


Вот что показвает Рефлектор:

private static void Main()
{
    int num1 = 0;
    Console.WriteLine(true);
    Console.WriteLine(false);
    Console.WriteLine(true);
    Console.WriteLine("+");
    Console.WriteLine("+");
}


да и ворнинги говорят, о том, что компилятор сам все решает.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: О nullable-типах и операторе "? :"
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.06 15:54
Оценка: +1
Здравствуйте, mihailik, Вы писали:

M>Ну она даже в CLR встроена, что уж там про компилятор говорить.


Зачем встроена поддержка в джит, понятно. Это сделано для эмуляции красобы при работе с боксингом.

А вот химия компилятора не очень очевидна.
... << RSDN@Home 1.2.0 alpha rev. 628>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: О nullable-типах и операторе "? :"
От: retn нет
Дата: 14.01.06 17:20
Оценка:
Здравствуйте, Alexander__S, Вы писали:

A__>Извините за настырность, но опять-таки, почему компилятора? Может быть, все-таки CLR в рантайме во время выполнения оператора is проверяет, является ли тип Nullable, инстанцированным данным типом?


Тут компилятор сразу пишет "результат"
int i = 0;
Console.WriteLine(i is int?);
Console.WriteLine(i is int? "+" : "-");


  .locals init ([0] int32 i)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  ldc.i4.1
  IL_0004:  call       void [mscorlib]System.Console::WriteLine(bool)
  IL_0009:  nop
  IL_000a:  ldstr      "+"
  IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0014:  nop
... << RSDN@Home 1.2.0 alpha rev. 629>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.