Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'static' keyword gets added to a function forward declaration based on its body contents #303

Open
gtrainavicius opened this issue Oct 16, 2018 · 4 comments
Labels
topic: code Related to content of the project itself topic: preprocessor Related to sketch preprocessing type: imperfection Perceived defect in any part of project

Comments

@gtrainavicius
Copy link

if strings.Index(tag.Code, STATIC+" ") != -1 {

Issue Description

I hit this issue after writing a complex macro which defines a 'strong' function implementation, and the code generated by the macro must be written in a very peculiar way. The idea is to allow easy overriding of a default 'weak' function, in order to let user easily customize an Arduino library I am writing without having to rely on config headers or custom board specifications. (https://github.com/BlokasLabs/USBMIDI, will commit the actual macros soon, will add a comment with a link to them)

The issue is that after preprocessing, the entire function lands in a single line, and the 'static' keyword gets added because such keyword is found within the implementation, but the Arduino Builder should only be concerned about the function prototype itself.

Example

Here's an example macro that would reproduce it if placed in .ino:

#define TEST() int test() \
    { \
        static int x = 5; \
        return x; \
    }

TEST();

The resulting forward declaration in the preprocessed sketch would end up like:

static int test();

int test() { static int x = 5; return x; };

Since the forward declaration is marked static, other compiled object files will not be able to see this implementation, and therefore the default implementation marked with the 'weak' attribute does not get overridden.

Expectation

The expected forward declaration would be int test();

Solution

I know that the current solution to workaround this would be to put this macro in a .cpp file, however, I would love to achieve the simplicity of simply dropping a macro call in single .ino file :)

I'd like to suggest making the check at:

if strings.Index(tag.Code, STATIC+" ") != -1 {
to check whether the 'static' that was found is not after a '(' or '{' within the same line, that should let it discard 'static' that could appear in the implementation body.

Additionally, there should be a check whether the 'static' is separated by whitespace from both sides, a bonus test case:

int function_static () // Note the space before ()
{
 return 5;
} 

Results in:

static int function_static();
@gtrainavicius
Copy link
Author

And one more test case:

void test() // static used in a comment on the same line
{
}

gets forward declared as:

static void test();

@facchinm
Copy link
Member

Wow, thanks for the very precise report.
Of course adding the static keyword in both cases is a bug; would you mind testing the same code by passing -experimental to the builder? This will trigger arduino-preprocessor to forward declare the prototypes instead than unhealthy ctags + manual parsing. For the sake of simplicity the beta version of the IDE already invokes it with that flag, if you prefer to test in a "real world" scenario.

@facchinm facchinm added the bug label Oct 16, 2018
@gtrainavicius
Copy link
Author

As promised, here's the macros: https://github.com/BlokasLabs/USBMIDI/blob/master/src/usbmidi.h#L54

And here's the default instantiation using the weak attribute: https://github.com/BlokasLabs/USBMIDI/blob/master/src/usbmidi_vusb.cpp#L199

As it's pretty difficult for Library developers to provide 'compile time' customization via preprocessor defines in the compiler command line, I'd definitely recommend use of weak symbols for Arduino. :)

Ok, I have tested with 1.9.0-beta and the issue does not reproduce - the macros work fine if placed in .ino file, so I guess this issue can be closed.

Btw, when do you expect to publicly release 1.9.0?

@facchinm
Copy link
Member

There are still a few regressions to be targeted before we can safely merge arduino-preprocessor support; of course testing is always welcome, so if you could use the build for a few weeks and report any regression you may find it would be great!

@per1234 per1234 removed the bug label Sep 16, 2021
@rsora rsora added topic: preprocessor Related to sketch preprocessing type: imperfection Perceived defect in any part of project and removed Component: preprocessor labels Sep 16, 2021
@per1234 per1234 added the topic: code Related to content of the project itself label Oct 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: code Related to content of the project itself topic: preprocessor Related to sketch preprocessing type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

4 participants