Assign To

Not sure that I agree that bugs should be closed as "by design" simply because we understand why they happen...

Posted by Lawrence [MSFT] on 4/22/2010 at 2:08 PM

Hello Andy,

Your assumptions are correct. The compiler is clever enough to figure out the situation within the function. So if you just had “memcpy(&local, &pram)” without the error-checking; the compiler will actually figure out that you don’t even need the param or local variable and just call printf on the constant value. This is because the compiler knows about memcpy and will try to convert it to a MOV instruction. After that, the compiler can do a variety of optimizations (such as Constant Folding, Stack Packing, Dead Code Removal, etc) which (depending on the code) can result in removing the MOV instruction as long as any dependency on the value are not broken.

An example is with why foo3 was able to print “OK!”. With foo3, you had a printf statement with the address of key_corr as an argument. The compiler has little knowledge of printf and can only deduce that printf can potentially hold a dependency on &key_corr (either by storing or retrieving information from that address space). So the compiler had to make sure that &key_corr does not share its address space with any other variables that can potentially change the value in the address. Foo1 and foo2 did not have this problem since there were no dependencies on the variables.

If you are interested you can look at the assembly listing using compiler flag /FA (this creates an assembly listing file with .asm extension). If you look under “_main PROC” you can see that there is only one MOV instruction (this is related to the memcpy called by foo3), the rest of the function has code on comparing the address values and calling printf on the constant value.

I hope this answers your question. Since this is the nature of the compiler during an optimize build I am going to close this item as resolved. Please do not hesitate to reactivate this MSConnect bug if you have related questions or found related issues.

Thank you,Lawrence Joel

Posted by Andy Kilpatrick on 4/21/2010 at 4:03 AM

In the case of my code, we memcpy the contents of the parameter (key_corr - or param in Daniel's example) to the local variable (pid, or local in Daniel's example). Our memcpy function asserts if the source and target are the same (as this is considered a bug in our coding standards) - the optimization causes this assert to be hit. (I've put this as a printf in my example code above rather than an assert()).

I assume the optimization can only happen because local=param at all times (or the values are not subsequently accessed). The optimizer is being clever enough to spot that the memcpy doesn't result in different values for the parameter / local variable? So if we had "memcpy(&local, &param);" instead of my error-checking version, would this be removed by the optimizer, or executed (with &local == &param)?

Posted by Lawrence [MSFT] on 4/19/2010 at 4:27 PM

Hello Daniel,

I am the developer assigned to investigate this issue. Thank you for the more readable repro in your last post. I will be referring to it when I describe the issue.

So this behavior is a result of the compiler inlining the function failOptimize which would then make the parameter param be a local variable. This would make param subject to optimizations; more specifically stack packing (an optimization that places local variables in the same stack address space to reduce stack space). This makes param and “local” share the same stack offset and so they would overlap. Based on the nature of the compiler this is by design for optimize builds.

What is the nature of your program that you require the parameter and local variable to not overlap? A simple workaround is to prevent the function from being inlined or to wrap the function with #pragma optimize ( “”, off).

Thank you,Lawrence Joel

Posted by Microsoft on 4/1/2010 at 8:34 PM

Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you

Posted by BlueRaja on 4/1/2010 at 2:08 PM

sorry forgot to mention, also using VS 2008 SP1, XP Pro.

Posted by BlueRaja on 4/1/2010 at 2:06 PM

I can confirm this behavior. Here is a version I think makes the problem more clear: