Why does short-circuiting not prevent MissingMethodException related to unreachable branch of logical AND (&&)?
Asked Answered
T

4

20

While performing a check if there's a camera present and enabled on my windows mobile unit I encountered something I don't understand.

The code looks like this:

    public static bool CameraP(){

        return Microsoft.WindowsMobile.Status.SystemState.CameraPresent;
    }

    public static bool CameraE()
    {
        return Microsoft.WindowsMobile.Status.SystemState.CameraEnabled;
    }

    public static bool CameraPresent1()
    {
        return Microsoft.WindowsMobile.Status.SystemState.CameraPresent
              && Microsoft.WindowsMobile.Status.SystemState.CameraEnabled;
    }

    public static bool CameraPresent2()
    {
        return CameraP() && CameraE();
    }

When I call CameraPresent2() it return false (there is no camera present). But when I call CameraPresent1() i recieve a MissingMethodException with comment "Could not find method: get_CameraEnabled Microsoft.WindowsMobile.Status.SystemState."

Is the second term evaluated in CameraPresent1 just because they both are property (at language level)?

Is there anything else that explains the difference in behaviour?

Thruway answered 8/3, 2011 at 13:31 Comment(7)
do you get the same exception if you call CameraE() ?Rodmun
"short-circuited" would be a better phrase than "lazy" here...Bodoni
The part that confuses me is I can't find a reference to CameraEnabled in msdn at all... I was going to go for "some custom overload of &&" though.Unseam
@Rodmun Yes, if I call CameraE() the same exception is thrown.Thruway
@Massif: Can't find it there either, but I can find it when I browse Microsoft.WindowsMobile.Status from VS2008. It works on other units that has a camera. This gives me some new ideas.Thruway
I think that the error occurs before it reaches the method, maybe you need a news version of the dll?Rodmun
Thanks to Ben Voigt's answer I realize that the title is quite misleading. Trying to figure out a better one.Thruway
P
31

The second term is not evaluated.

The first term is not evaluated.

The CameraPresent1() method does not even start to execute.

When you call CameraPresent1() for the first time, the runtime must JIT-compile the MSIL into native code. This requires resolving all method calls, even ones that might be reached only conditionally. Compilation fails with the MissingMethodException.

With CameraPresent2(), the call to the getter of CameraEnabled is only compiled when CameraE() is called for the first time, which never happens.

Proffer answered 8/3, 2011 at 14:2 Comment(3)
great answer - and actually answers the questionSkelp
Thanks! This Gave me some great insight, not only to my problem but also to how and when the JIT-compiler works.Thruway
To answer Fritz's comment, which due to low rep was placed in an answer, and due to poor word choice was deleted by a mod -- properties do not perform faster than methods. A property is nothing but syntactic sugar for a pair of methods, the getter and setter. (Syntactic sugar means the compiler turns it into the same output executable)Proffer
H
10

C# Specification section 7.12

The && and || operators are called the conditional logical operators. They are also called the “short-circuiting” logical operators.

The && and || operators are conditional versions of the & and | operators:

  • The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is not false.

  • The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.


That is to say that the C# spec guarantees that CameraE() will be called if and only if CameraP() is true.

This may be an issue with aggressive compiler optimizations, and therefore the actual program seems to violate the language spec...


Edit:

Is it possible to put up a breakpoint and show the disassembly window, to see the exact code generated?

Heraldic answered 8/3, 2011 at 13:32 Comment(7)
I think he's asking why it appears as though && is not lazy in the call to CameraPresent1.Osterhus
@Marc: I... had no idea... I thought that that was just for bit-twiddling... oh, my god, I'm so bad at this....Heraldic
RB is correct. How come that the && operator works as if it's not short-circuited. I'll edit the question headline.Thruway
what does "short-circuited" mean?Rodmun
@John Gietzen: But what about CameraPresent1()? Apparently the second argument is evaluated. Is this something I should consider as a bug in VS2008 implementation?Thruway
@nj, that's what I'm thinking. Can you show the disassembly window while it is running?Heraldic
@John Working on it. I've tried to put a break point inside CameraPresent1(), but it never reaches it. Could it be because some difference between the libraries that's loaded in VS2008 and the one available on the device?Thruway
S
5

Just a wild guess, but is it possible that this is a JIT compilation issue? When CameraPresent1 is called, is it attempting to map the call Microsoft.WindowsMobile.Status.SystemState.CameraEnabled to the underlying device? Since it cannot find the method get_CameraEnabled, the entire function fails with a MissingMethodException.

Slug answered 8/3, 2011 at 14:0 Comment(5)
I'm just trying to repro the problem, but can't compile because the CameraEnabled cannot be found. Is the app compiling for you? What project references do you have?Slug
@Justin Largey: The runtime version of Microsoft.WindowsMobile.Status is v1.1.4322.Thruway
Interesting, that's the exact same version I have. I cannot seem to find CameraEnabled anywhere. In your code, can you try selecting the CameraEnabled propery, and hit F12 (Go To Definition). Does VS actually take you to the definition of this property? Is is possible that the project is referencing an assembly that is augmenting against the MS.WindowsMobile.Status namespace? Or that there is a mismatch with the runtime in VS and the runtime on the phone. (i.e the runtime in VS thinks there is a CameraEnabled property, however the actual runtime on the phone does not have it.)Slug
I can navigate to the definition from my code. What target platform are you using? I currently only got Windows Mobile 6 SDK installed so I can't double check if it's available in WM5 as well. But since it only have failed on devices with WM5 I guess this could be where the mistake was done.Thruway
I think you're right. I have Windows Mobile 5 SDK, which does not have the CameraEnabled property. However, I'm guessing the v6 SDK does have this property. This also explains why it works on WM6, but not WM5.Slug
B
0

Looking at the problem as reported, it seems to make no sense. The two versions should be identical. I wonder, though, if the problem here is that the camera API is using dynamic at some point, and it is trying to look for a true()/false()/& operator. This might convince it to switch to bool logic:

public static bool CameraPresent1()
{
    return ((bool)Microsoft.WindowsMobile.Status.SystemState.CameraPresent)
          && ((bool)Microsoft.WindowsMobile.Status.SystemState.CameraEnabled);
}
Bodoni answered 8/3, 2011 at 13:57 Comment(1)
Still won't enter CameraPresent1(). I'm leaning more towards Ben Voigt's answer.Thruway

© 2022 - 2024 — McMap. All rights reserved.