Odd compiler errors with SDK 7.4.1

I'm aware of the previous export problem with SDK 7.4.0, and while my issue below may be a duplicate of this post but I wanted to start a new thread with a more appropriate thread subject/title.

I was compiling and running locally (in the sim) one of my apps just fine with SDK 7.3.1, however when I downloaded SDK 7.4.1 the unchanged code was reporting 6 new errors.

Two of the errors were "Statement is not reachable" errors, which I easily tracked down to functions not marked as potentially returning Null.

The other errors, however, are very strange and are contained with the onTap() function of an InputDelegate.

var coords = clickEvent.getCoordinates();
for (var i=1; i <= 12; i++) {
  // do whatever
  var drawable = _view.findDrawableById("someID");
  if ( != null) {
    // do stuff
    break;
  }
}
The above code generates two errors:
  • Trying to access an uninitialized variable.
  • Cannot perform operation 'add' on types 'Uninitialized' and '$.Toybox.Lang.Number'.

I've isolated this down to the i++ portion of the for-loop and don't see how I can possibly work around this. I have tried changing it to a while-loop, moving the code location, changed variable names, defined the counter/index outside of the loop, changed the way the addition is done, etc but the end result is always the same errors.

Top Replies

All Replies

  • Pray Thank you! I really appreciate the confirmation.

    I think to 's point above, some of us developers are deeply invested in the success of ConnectIQ and happy to contribute meaningfully to make it better.  We would welcome more avenues to be a part of the success story, including beta testing SDKs or otherwise supporting the platform's health and growth.

  • Should be early next week, unfortunately there's too many cranks to turn to get a release out today. We're rolling back the change that caused the issue for 7.4.2 but we will include it in a future release.

  • Thanks for the offer. We do have a beta tester program but it is currently not open for additional developers. I'll pass your names along for consideration in case it opens up in the future.

  • Yes, this is the same issue I was reporting to you via email (I could not attach the code on the forums).

  • Another Error, which did not occur before 7.4.1:

            // read HR Zonen
            sportArt = UserProfile.getCurrentSport();
            var hrZones = UserProfile.getHeartRateZones(sportArt);

            if (hrZones == null) {
                //no HR Zones available
                hrZones = [185, 187, 189, 191, 193, 195];    //fake zones instead  -->  will then show always zone 0 !
            }

    The bold line throws an Error:
    ERROR: edge1040: C:\Garmin_IQ_Projekte\Edge1_Ebike\source\EdgeAllinOne1View.mc:1013,12: Statement is not reachable.
    This error occurs also on other IF xxx == null   statements. Always occurs if condition "== null" is asked.
    The error does not occur with TYPECHECK = OFF.
    (sorry - I'm not allowed to insert a code window...)
  • according to the docs it can not return a null ( https://developer.garmin.com/connect-iq/api-docs/Toybox/UserProfile.html#getHeartRateZones-instance_function )

    but I've also implemented similar if constructions in the past as I think I've indeed seen cases where the hr zone array was returned as null, so probably the definition should be adjusted.

  • I also thought, the hr zone array cannot be null.

    After getting (seldom) ERA reports of crashes after reading the hr zone array, I implemented this for security reasons….

  • I just wanted to chime in with a hearty +1 on this:

    The compiler should NOT error due to what it determines is "unreachable" code solely due to type checking. 

    We can't fully rely on type declarations. The number of times Toybox APIs (and even my own code!) return undocumented types is high enough that we all need to build these extra protections, and we can't have the compiler forcing us to make our code less stable.

  • // isn't it the point of type checking that you can rely on what the statements will return?

    imho if there's a case where it can return null then the correct solution for this case is to adjust the api to 

    getHeartRateZones(sport as UserProfile.SportHrZone) as Lang.Array<Lang.Number> or Null

  • I agree that we should all prefer & aim to write type-safe code.  But I've been burned enough through my decades coding to know that we need to write code to prepare for mistakes (or system errors), not just hope everyone does their job perfectly.

    If MonkeyC was a strictly typed language (like Java), then I agree that this perspective of "trust the types" should work.

    But MonkeyC is not actually a typed language (the types are layered in as optional).  It is possible to mix typed and untyped code. And even Garmin APIs sometimes have mistakes where they return types not specified by the API.

    The documentation directly supports my assertion that we should write defensive code and the compiler can't check all issues:

    Monkey C is a duck typed language.... 

    The Monkey C compiler does not verify type safety, however, and instead runtime errors occur when functions mishandle objects. This provides great flexibility to developers, but in exchange the compiler cannot perform static type checking like in C++ or Java. Using operators like instanceof and has can help avoid potential typing issues.

    Sure, we could hope for the Toybox APIs to be better.  And we could try harder to make our code perfect.  But if there is ever the possibility of a type not matching it's declaration, then I think we need to allow code that "sanity checks" the value.

    Therefore, I feel strongly that if the Monkey C bible says "Monkey C compiler does not verify type safety", then the compiler should NOT error due to what it determines is "unreachable" code solely due to type checking. 

    The SDK cannot in one place say "We don't guarantee types are checked" and then generate fatal errors that imply "you can't write code that gut-checks types".