Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why you cannot use an unsafe keyword in an iterator context?

In looking at this question which Jon did a fine job in answering... 'How to read a text file reversly with iterator'. And there was a similar question in which I answered using pointers hocus pocus..'.net is there a way to read a text file from bottom to top' before it got closed....

Now I did set out to try solve this using pointers, ok, it looks hackish and rough around the edges...

public class ReadChar : IEnumerable<char>
{
    private Stream _strm = null;
    private string _str = string.Empty;
    public ReadChar(string s)
    {
        this._str = s;
    }
    public ReadChar(Stream strm)
    {
        this._strm = strm;
    }
    public IEnumerator<char> GetEnumerator()
    {
        if (this._strm != null && this._strm.CanRead && this._strm.CanSeek)
        {
            return ReverseReadStream();
        }
        if (this._str.Length > 0)
        {
            return ReverseRead();
        }
        return null;
    }

    private IEnumerator<char> ReverseReadStream()
    {
        long lIndex = this._strm.Length;
        while (lIndex != 0 && this._strm.Position != 0)
        {
            this._strm.Seek(lIndex--, SeekOrigin.End);
            int nByte = this._strm.ReadByte();
            yield return (char)nByte; 
        }
    }

    private IEnumerator<char> ReverseRead()
    {
        unsafe
        {
            fixed (char* beg = this._str)
            {
                char* p = beg + this._str.Length;
                while (p-- != beg)
                {
                    yield return *p;
                }
            }
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

but discovered that C# compiler cannot handle this using this implementation but was devastated when the C# compiler refused with an error CS1629 - 'Unsafe code may not appear in iterators'

Why is that so?

like image 394
t0mm13b Avatar asked Feb 11 '10 00:02

t0mm13b


People also ask

What is the use of unsafe keyword?

The unsafe keyword denotes an unsafe context, which is required for any operation involving pointers. For more information, see Unsafe Code and Pointers. unsafe static void FastCopy(byte[] src, byte[] dst, int count) { // Unsafe context: can use pointers here. }

How can use unsafe context in C#?

C# supports an unsafe context where we can write code whose security is unverifiable by the CLR. For example, by default, C# does not support pointer arithmetic to ensure type safety and security. However, in an unsafe context, we can use pointers. To denote an unsafe context in C#, we use the unsafe keyword.

Which type is used in unsafe mode?

Now to understand what UnsafeMode is. Unsafe is a C# programming language keyword to denote a section of code that is not managed by the Common Language Runtime (CLR) of the . NET Framework, or unmanaged code. Unsafe is used in the declaration of a type or member or to specify a block code.


2 Answers

Eric Lippert has an excellent blog post on this topic here: Iterator Blocks, Part Six: Why no unsafe code?

like image 114
Kevin Pullin Avatar answered Sep 24 '22 23:09

Kevin Pullin


What I want to know is why you would use pointers for this at all. Why not simply say:

private IEnumerator<char> ReverseRead()
{
    int len = _str.Length;
    for(int i = 0; i < len; ++i)
        yield return _str[len - i - 1];
}

What's the compelling benefit of messing around with pointers?

like image 20
Eric Lippert Avatar answered Sep 24 '22 23:09

Eric Lippert