NCS Does Not Respect C Rule Against Function Overloads Under Certain Conditions

During a review of production firmware I noticed an oddity that should cause a compiler error but it somehow does not.

In C, a function may not be overloaded. There are exceptions to this (with _Generic), but we are not engaging with this functionality. We have accidentally included a function overload in a C source file, which the Intellisense correctly marks as an error. However, the compiler does not think it is an error. I am using NCS 2.5.1 with the ARM GNU toolchain 9-2019-q4-major. Zephyr version 3.4.99. I modified the blinky sample application to replicate the issue.

Consider this code:

void test();

void function()
{
    test();
}

void test(void * arg)
{
    arbitrary_code();
}

void function2()
{
    test(NULL);
}

In the code, test() is initially declared to be parameter-less and then invoked. However, further down test() is defined as a parametrized function and invoked as such. This should cause an error in C. I tried this with a different set of build tools (IAR) and they correctly identified this as an error.

Interestingly, if you change the order of the statements, the error is caught. It seems that this compiler glitch only happens if you have a declaration with its invocation written before the function is "redefined" and used with the other signature.

  • Hi,

    This likely occurs because of how lenient or strict different compilers are with the checking. In your case, even though function overloading is not allowed, you actually have two versions of the test function.

    So in your sample, you first have a function declaration as:

    void test();

    Now, C is less strict about function declarations compared to C++. Hence when you have this declaration it likely understands it as a function which can take any arguments and return a void. So later when you have the definition as follows:

    void test(void * arg)
    {
        arbitrary_code();
    }

    It does not actually violate what you have declared before. What you have done here is incomplete function prototyping. Certain compilers are lenient with this and others like the IAR are a bit more strict with this. The better solution is to avoid incomplete function prototyping and declare it properly always.

    Hope this helps.

    Regards,

    Priyanka

  • There are usually 2 compiler settings.  One for treat warnings as error. The other is disable all warning.  Normally this should show a warning. If you don't see it, the disable all warnings may be active. Unfortunately, I don't know where those settings are in NCS. Look for the compiler settings.  You might find tons of warning once you enable it. ;)

  • Ahh, I was unaware this was a "feature" of C in the old days. I looked around the internet with better keywords (incomplete function prototype) and found that the compiler setting -Wstrict-prototypes will mark instances of this.

    I now understand the value of placing void in the parameter list, like void test(void).

    Thanks for your help, Priyanka.

Related