Connect IQ > 4.1.6 - problem with overriding functions

I've following hierarchy:

    Setup extends BaseSetup
    BaseSetup extends CoreSetup
    CoreSetup
    
    My setup class implements following:
    
        function load()
    
    My BaseSetup implements following:
    
        protected function load(key, numberOfDataFields)
    
    My CoreSetup following:
    
        protected function load(key, numberOfDataFields)

As you can see the BaseSetup overrides the function of the CoreSetup.

As you can see as well, the final Setup class wants to define a load function that does NOT override any base functions but this does not work anymore in CIQ 4.1.6 and CIQ 4.1.7
    
I get following error: Cannot override '$.BaseSetup.load' with a different number of parameters.

Question

In the past the compiler was smart enough to detect that functions with different parameters do NOT override the function in the parent class. Is this a new "rule" that functions with same names are not allowed anymore? Do I really need to use different names now for all functions even if I use different parameters?

  • What code calls either load() or load(k, n)?
    Whith what flags do you call the compiler? -l ???

  • No flags... Could find a solution though as it seems to be a problem in some pre compile check only as the compiled result will work fine: I simply disable the typechecks and now it works (with project.typecheck = 0 inside my monkey.jungle file)... I don't use types yet anyways...

  • With the current SDKs, by default type checking is on, and by adding that line in monkey.jungle, it turns it off for that project.  Sounds like you may want to do a bug report with a simple sample that shows this issue.

  • The 4.1.7 and 4.1.6 have a lot of problems compiling it gives errors that are not present in 4.1.5

  • Now you can learn :) Some of those are actual bugs (yours), some are bad habit, and some are kind of bugs of Garmin in a sense that it enforces you to add things like "as Number" when a variable is declared like "as Number?" and you know that in a certain point of the code it can't be null but the compiler doesn't figure it out.

    This will sound contra-intuitive, but the more these warnings/errors give someone a hard time (aka the newer they are to Monkey C, and even more so if they are new to programming) the more it is useful and help them because it forces better code and fixes some bugs that would not be seen with previous compiler (or the new but the warnings disabled) and then they would cause errors for users, when it's much harder to fix (not to talk about the reputation of the app...)

  • this is the error I get

    BUILD: ERROR: vivoactive_hr:
    /Users/lcda/eclipse-workspace/PowerBikeWind/PowerBikeWind-Master/source-fr920xt/PowerBikeWindView.mc:11: Redefinition of '$.PowerBikeWindView'. Previous definition at /Users/lcda/eclipse-workspace/PowerBikeWind/PowerBikeWind-Master/source/PowerBikeWindView.mc:12.

    BUILD: WARNING: vivoactive_hr: The <build> tag has been deprecated. Please use Jungle files for build exclusions.

    and this ara my jungle strings

    vivoactive_hr.sourcePath = source;source-fr920xt

    vivoactive_hr.excludeAnnotations=source

    vivoactive_hr.resourcePath = resources;resources-fr920xt



    sorry I reported my own replay as abusive by error

     

  • Well, to be fair, Monkey C has never generally supported functions with the same name but different numbers of parameters, in the same scope.

    For example, I'm pretty sure what you've described in the OP has never worked with two functions at the global scope or two functions on a single class.

    The fact that you were able to do so with a derived class seems like more of an oversight or bug than a feature. It just may have been that the old compiler didn't actively prevent people from taking advantage of this oversight.

    In other words, Monkey C doesn't have function polymorphism like C++ or Java, whereby two functions in the same scope can have the same name and are distinguished by the number and types of their parameters.

    In the past the compiler was smart enough to detect that functions with different parameters do NOT override the function in the parent class

    Depending on how you look at it, they kind of did, since defining load() on the derived class effectively "hides" the parent classes' load() function.

  • Or worse: I bet it woks only one way, and it's probably when you override a function with more parameters in the parent class with a function that has less parameters in the child class. Because if my guess is correct then the following will get some garbage:

    class A {
        function f(a) {
            // use a
        }
        function g() {
            f(1);
        }
    }
    class B extends A {
        function f(a, b) {
            // use both a and b
        }
    }

    My guess is that in this case when g calls f with 1 parameter then either A.f is called which is probably not what you wanted, or B.f is called but only with 1 parameter, and thus you either get some problem because B.f is trying to get b from the stack, or it does get some garbage, and the worst is that it even modifies something in the memory (let's say b is a record) and it overrides some memory area with "garbage" that will crash the app later when it's used, and you won't have any idea what happened.

  • I can't really help with the error. Not because it's not clear, but because it's very clear. So if you don't understand then I won't be able to explain. Look at the 2 lines it complains about. Both declare the same global variable, and because of your jungle file it loads both (because: vivoactive_hr.sourcePath = source;source-fr920xt)

    The usual way is to have the common things in source (and only there) and have the other things under the source-<...> directories, but you have to make sure that whatever is there is in all the "brother" directories of the same "dimension". So if you have it in source-fr920xt then you have to have it in the other sorurce-<device> directories as well (probably)

    Ah, I know what happened!!!!

    You misunderstand what vivoactive_hr.excludeAnnotations=source means: it's not excluding the source directory. You have to use it as annotations in the code. So you could do this in source/PowerBikeWindView.mc:12:
    (:source) $.PowerBikeWindView = ...;

    But this is a hack. You probably either should use the folders or the annotations, but having them mixed like this makes no sense. You could just have 2 lines in source/PowerBikeWindView.mc (and no source-fr920xt/):

    (:base) $.PowerBikeWindView = foo;
    (:fr920xt) $.PowerBikeWindView = bar;

     

  • I think my jungle are too old can you give me an example of new jungle files

    I got this on jungle but it's not working with 4.1.7

    project.manifest = manifest.xml
    srcBase=source
    resBase=resources
    
    base.sourcePath = $source(srcBase)
    base.resourcePath = $resource(resBase)
    
    base.excludeAnnotations = source-fenix3
    base.excludeAnnotations = source-fr230
    base.excludeAnnotations = source-vivoactive_hr
    
    vivoactive_hr.sourcePath = $(vivoactive_hr.sourcePath);source-vivoactive_hr
    vivoactive_hr.resourcePath = $(vivoactive_hr.resourcePath);resources-vivoactive_hr
    vivoactive_hr.excludeAnnotations = source


    my directories are this