Let's suppose you've just created a new Arduino project using PlatformIO, or an IDE like Sloeber. You now have a file named "main.cpp" with two functions (methods?):

  • void setup()
  • void loop()

Now, suppose you follow Arduino coding norms, and stick something at the top like:

hd44780_I2Cexp lcd(0x27);

Is the hd44780_I2Cexp object instantiated by it static? Or is main.cpp #include'd into some class in a way that makes everything in it private or public members of that class?

If they're instance methods, is it absolutely 100% guaranteed that the instance is, and forever shall be, a singleton? Or is there any conceivable scenario where there could be two simultaneous instances of it (say, if you were using both cores of an ESP32)?

If it's an instance, but guaranteed to forever be singleton on any future platform that calls itself "Arduino", is there any need to care about the distinction between "instance member" and "static variable" (in the context of main.cpp)?

Should main.cpp "really" have a separate main.h file, and "official" public: and private: blocks for the sake of C++ linguistic purity, or would I just be creating real or potential problems for the sake of intellectual exercise and ideology?

  • 2
    public and private are for classes. main isn't a class nor is it in one. It's just a function. The lcd object you describe creating is at global scope. It's not part of an instance of any class. I think maybe you are confusing this with java.
    – Delta_G
    Jul 5, 2023 at 3:59
  • 1
    The lcd variable you create is not static nor is it an instance variable. It is an instance of the hd44780_I2Cexp class that is at global scope. It's not a member of anything. It's not an instance variable of anything. It's not static. It's just a global object.
    – Delta_G
    Jul 5, 2023 at 4:01
  • If you examine the output when building in verbose mode you'll find mentioned an .ino.cpp file in a temp directory. This is the result of the build process, the documentation for which probably tells you everything you want to know, if not .ino.cpp file doesn't.
    – timemage
    Jul 6, 2023 at 0:07

2 Answers 2


In the Arduino IDE, setup and loop are functions, not instances of anything.

There is a file included in the compilation sequence, main.cpp, which has the following code (slightly simplified here):

#include <Arduino.h>

int main(void)

    for (;;) {
    return 0;

So you can see that this bit of "sugar" basically calls setup once and loop repeatedly.

The other function, init, initialises some hardware, like the timers, so that millis() and delay() work as documented.

I can't speak for other IDEs but I assume they do similar things, in order to be compatible.


Whatever you define outside of any function will be global, which is static - it lives for the duration of program execution - and visible to all compilation units that are bound into the eventual execution unit.

If you also include the 'static' declaration ahead of the type, the variable will be file-level static, meaning it will be visibile only within the current file.

This is standard C/C++ behavior for any data type - scalars; vectors, structs & arrays; and objects (C++ only, of course).

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.