3

I am trying to make my own library and it uses some local variables with the same name as some variables in ino. Compiler complains about it. I stripped it to (nonsence but simple) example

mylib.h:

#ifndef MYLIB_H
#define MYLIB_H
int doit();
#endif

mylib.cpp:

#include "mylib.h"
int value;
int doit(){
    return value++;
}

example.ino:

#include "mylib.h"
int value;
void setup(){
    value=3;
    pinMode(13,OUTPUT);

}
void loop() {
    digitalWrite(13,(value==doit()) );
}

compiling:

$ make
/usr/bin/avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p example.o mylib.o .lib/arduino.a -lm -o example.elf
mylib.o:(.bss.value+0x0): multiple definition of `value'
example.o:(.bss.value+0x0): first defined here
collect2: error: ld returned 1 exit status
/home/gilhad/GIT/HW/Arduino/minipro//../Arduino.mk:436: recipe for target 'example.elf' failed
make: *** [example.elf] Error 1

I am not usint the value in the .h file, so why it collides with similary named variable from another module?

Should not be it private to the module until exposed via .h file?

5
  • 2
    Try the keyword "static". stackoverflow.com/questions/572547/what-does-static-mean Oct 8, 2017 at 13:09
  • Thank you, it completly explains my question (and some more). If you make it answer, I would accept + upvoted it, as it provided good inside for me to the whole problem :)
    – gilhad
    Oct 8, 2017 at 13:26
  • @MikaelPatel, can you explain why this works? From my perspective, gihad should subscribe to creating Arduino libraries using C++ (not just C) and create a class where the library's private variables would be protected (not even seen) from the Arduino sketch.
    – st2000
    Oct 8, 2017 at 15:23
  • As a fact of matter, it was not even my code, but my 13-years old nephew's. And he was trying to separate few common used functions (many of which had nothing common) away for his playing with some LEDs and displays, to use it in more versions of the same program (Hello world, Hello city and such). And few of that functions shared some settings (LedOn, Color, Value).
    – gilhad
    Oct 8, 2017 at 17:20
  • And it did not compile, so he asked me, why and I did not know. I would wrote it in totally different way and I would not hit such problem, but I could not find, why it is not working. And say "do it much complicated way and do not even ask why it does not work this way" is not good approach in teaching. Also it signalled, that I do not know something, which I should know. And I am planning to write much complicated projects, so I want to know not only how make things nice, but also how it works under hooks when I want to poke really deep :)
    – gilhad
    Oct 8, 2017 at 17:24

2 Answers 2

1

I am not usint the value in the .h file, so why it collides with similary named variable from another module?

Should not be it private to the module until exposed via .h file?

The quick answer is that a source code file is not a separate unit. The last step in the build process is to link all the object file and create the executable binary. The linker will need to resolve all the symbols. In this case there are two definitions and the compiler cannot resolve the references. The linker can be told to ignore multiple definitions.

The keyword "static" will make the symbol local to the compiled unit (object file). As the keyword "external" tells the compiler that the definition is in another compiled unit. Header files is just a structuring convention. The language does not actually say anything about this. It is a pre-processor (cpp) in the build process that creates the combined source code for the compiler.

C++ (and OOP) adds a number of ways to control the visibility of symbols (aka encapsulation). In a class definition the keywords "public", "protected" and "private" may be used. Also the keyword "static" may be used. In this case it means that the symbol is defined globally for the class (class variable) and not per instance (member variable).

The keyword "static" in C/C++ is actually a "recent" development of the languages. In the early versions of C local symbols where prefixed with underscore "_local". This is still a common practice even though the object files contain much more scope information today.

Cheers!

1

The common practice is to write Arduino libraries using C++ classes:

The core of the header file consists of a line for each function in the library, wrapped up in a class along with any variables you need.

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
  private:
    int _pin;
};

In this way you can specify what is private (variables and methods only seen within the class) and what is public (variables and methods that can be seen outside the class). In the given example, the variable called "_pin" is private to the class Morse.

In your case, you would want to make a private class variable called "value". Because it is private, you are free to re-use the name when not inside the class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.