Does it make any difference to use unsafe inside or outside a loop?
Asked Answered
E

2

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.
        }
    }
}
Emma answered 22/1, 2016 at 14:6 Comment(5)
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.Disoperation
@Disoperation - 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.Emma
@Emma does not seem to be an easy question to answer.. you may need to wait patiently.. ;) I am interested to know the explanation tooIpecac
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.Layard
I think the first block of code would confuse people and make them wonder why the loops are unsafe.Strauss
E
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.

Erena answered 22/1, 2016 at 14:23 Comment(0)
T
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

Torsion answered 22/1, 2016 at 14:16 Comment(12)
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. @Emma if you want a design advice, rather than just a technical advice, try the CodeReview.SE.Dyewood
@Dyewood - 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.Emma
@Dyewood 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.Dragline
@Dragline 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?Dyewood
@Dyewood "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.Dragline
@Dragline what is an example of where wrapping the code in an unsafe context matters?Diagnostic
@Diagnostic Readability, maintainability, and correctly indicating which portions of the code are, in fact, unsafe.Dragline
@Dragline - 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.Torsion
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.Dragline
@Dragline - it's purpose is to change what the compiler will accept and produce output for. That's literally the first sentence of my answer.Torsion
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.Underestimate
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.Tilden

© 2022 - 2024 — McMap. All rights reserved.