65

I never needed to use unsafe in the past, but now I need it to work with a pointer manipulating a bitmap.

I couldn't find any documentation that indicates otherwise, but I would like to understand better how unsafe works and if it makes any difference to use it inside or outside a loop.

Is it better to do:

unsafe
{
    for (int x = 0; x < maxX; x++)
    {
        for (int y = 0; y < maxY; y++)
        {           
            //Unsafe pointer operations here.
        }
    }
}

Or to do?:

for (int x = 0; x < maxX; x++)
{
    for (int y = 0; y < maxY; y++)
    {   
        unsafe
        {       
            //Unsafe pointer operations here.
        }
    }
}
Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
Dzyann
  • 5,062
  • 11
  • 63
  • 95
  • 3
    I would think it is better to do the second one, considering the for loops themselves don't need to be `unsafe` and you would want to minimize the `unsafe` area. Unless, there is some sort of an overhead to calling it in a loop. – AustinWBryan Jan 22 '16 at 14:10
  • @AustinWBryan - From what I have read, it would seem you are right and it is what we are doing, but I would like to understand better what is the difference. – Dzyann Jan 22 '16 at 14:14
  • @Dzyann does not seem to be an easy question to answer.. you may need to wait patiently.. ;) I am interested to know the explanation too – Ian Jan 22 '16 at 14:15
  • 1
    I highly doubt there is any difference in terms of code generated. The main difference would be reducing the `unsafe` footprint of the code. Why include more than you need to in the unsafe block? It just creates additional lines of code where you can make mistakes outside the norm. – Glorin Oakenfoot Jan 22 '16 at 14:19
  • 3
    I think the first block of code would confuse people and make them wonder why the loops are `unsafe`. – Drew Kennedy Jan 22 '16 at 14:25

2 Answers2

56

unsafe keyword is a marker that you use to tell the compiler that you know what you are doing. Its main purpose is similar to documenting your code: unsafe block shows parts of your code that you designate as unmanaged territory; there is no impact on the actual execution of code.

With this in mind, it makes sense to reduce the size of this unsafe territory as much as possible, which means that your second approach is better than the first one.

It is worth mentioning that two other alternatives, i.e. marking the method and marking the class with unsafe, are also inferior to the approach when the unsafe block is placed around the smallest possible portion of the code.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
37

unsafe changes which expressions the compiler will accept and produce output for. It imposes no runtime overhead, in and of itself. For any expression that doesn't require unsafe, the compiler will emit the same code whether its within an unsafe context or not.

For the specifics of which expressions can only be used within an unsafe context, I'd recommend consulting section 18 of the C# Language Specification

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • 4
    And for the inevitable comments that say this doesn't answer the question: this gets as close to answering the question as possible, given that the question is off-topic on StackOverflow. @Dzyann if you want a design advice, rather than just a technical advice, try the CodeReview.SE. – Luaan Jan 22 '16 at 14:22
  • 1
    @Luaan - Thanks for pointing this out. I don't really look at this as design advice as I have stripped the code on the question of our actual design. My interest was referred to the way unsafe works, because I searched around and it was not clear to me. – Dzyann Jan 22 '16 at 15:07
  • 9
    @Luaan No, it *doesn't* answer the question. Is the question borderline between SO and CR? Yes. Does that mean it can't be on SO? I don't think so, but if you do you should vote to close it as off-topic. But any answer to the question has to answer the question, and this doesn't. Giving a half-answer is not the appropriate response to thinking a question is off-topic; voting to migrate it is. – KRyan Jan 22 '16 at 15:29
  • 1
    @KRyan Umm, did you read the answer? It basically says "the two produce the exact same bytecode". What kind of answer would you imagine fitting better? – Luaan Jan 22 '16 at 15:59
  • @Luaan "I would like to understand better how unsafe works and if it makes any difference to use it inside or outside a loop," and this only answers half of that. If `unsafe` doesn't change the bytecode, what *does* it do? and how does that inform where it should be used? Reading this answer, it implies that you can put `unsafe` wherever you want and it won't matter because it doesn't change the bytecode, and that's *not* true. – KRyan Jan 22 '16 at 16:00
  • @KRyan what is an example of where wrapping the code in an unsafe context matters? – clcto Jan 22 '16 at 16:40
  • @clcto Readability, maintainability, and correctly indicating which portions of the code are, in fact, unsafe. – KRyan Jan 22 '16 at 16:48
  • @KRyan - if you have a code base that currently compiles, and doesn't use `unsafe` anywhere, then yes, that's exactly what I'm saying - it won't change what the compiler produces. What it does is change the language that the compiler accepts, but it changes it to a superset of what you can use without it. – Damien_The_Unbeliever Jan 22 '16 at 17:25
  • Yes, and that's an incomplete answer. The keyword doesn't exist just for fun; it has a purpose, which this answer doesn't explain, and that purpose does inform whether the keyword should appear inside or outside the loops. – KRyan Jan 22 '16 at 17:26
  • 2
    @KRyan - it's purpose is to change what the compiler will *accept* and produce output for. That's literally the first sentence of my answer. – Damien_The_Unbeliever Jan 22 '16 at 17:27
  • I consider this does answer the the two (implied) questions. The question about how `unsafe` works is answered by "it changes what expressions the compiler accepts and produces output for". The question of whether it makes a difference in a loop is quite clearly "if the code compiles, `unsafe` makes no difference". Other opinion-based questions like "is it considered good practice to do it in a loop?" were not asked, and are not answered. – Peter Jan 22 '16 at 23:11
  • Yes, this answers the question. Anyone stating otherwise needs to visit meta more often. This whole off topic comment thread should probably be removed as a result. The failed argument "This doesn't answer the question" is a common one which has no bearing here at Stack Overflow. If the answer is an *attempt* to answer the question, it is an answer. Full stop. Move on with your life. All that is left after that point would be to determine the value of its use. This answer directly points to compiler expressions, which is probably as far as it had to go considering the nature of the question. – Travis J Jan 25 '16 at 17:21