Arduinoのmain関数について調べてみた

こんにちは。ハロです。

Arduinoって手軽で良いですよね。プログラムも基本的に書く必要があるのはsetup関数とloop関数だけだし、電子工作でいろいろ実験するのに最適だと思います。

今回はそんなArduinoのmain関数について調べてみました。

main関数はどこ?

Arduino IDEでスケッチを書くとき、CやC++っぽいなと思いますよね。それもそのはずで Arduinoの公式FAQ を見ると

Can I program the Arduino board in C?

In fact, you already are; the Arduino language is merely a set of C/C++ functions that can be called from your code. Your sketch undergoes minor changes (e.g. automatic generation of function prototypes) and then is passed directly to a C/C++ compiler (avr-g++). All standard C and C++ constructs supported by avr-g++ should work in Arduino. For more details, see the page on the Arduino build process.

ということなので、CとC++でのプログラミングはしっかりサポートされている訳です。このFAQから、ArduinoのスケッチでCやC++が使えるのは、スケッチをビルドする過程でマイナーチェンジしてavr-g++でコンパイルしているからと分かりますね。

では、ユーザーの書いたsetup関数とloop関数はどんな風にmain関数と結びついているのでしょうか。実は、Arduinoのインストールディレクトリの中を探してみると、main.cppが見つかります。実はこのファイルにmain関数が書いてあるんですね。

パスは私の環境では C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino でした。

main関数の中身

このmain.cppを開き、コメントなどを除いて抜粋したものが次のコードです。

#include <Arduino.h>

int atexit(void (* /*func*/ )()) { return 0; }

void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
    init();

    initVariant();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

これを見ると、ユーザーの書いたsetup関数やloop関数が、main関数とどう結びついているか分かりますね。Arduinoを使い始めた頃「なんでmain関数なくても動くんだろう」と思ったりしましたが、実はちゃんとあったんです。すっきりしました。

avr-g++コンパイラ

さて、このあたりまで調べると、avr-g++コンパイラでC++の機能がどのあたりまで使えるのかも気になってきますよね。

C++03、C++11、C++14、C++17、C++20などあるけれど、どこまで使えるのかな?

私のPCにインストールされているArduino IDEのavr-g++バージョンを確認すると

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin>avr-g++.exe --version
avr-g++.exe (GCC) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

GCC 7.3.0と表示されました。なので C++ Standards Support in GCC によればC++17は使えそうな感じですね。本当は、ビルドオプションでC++17が有効になっているかどうかも確かめたかったのですが、そこまでは調べきれませんでした。

感想

Arduinoの奥というか中身について、少しだけ詳しくなった気がします。

もしビルドプロセスまで詳しく分かったときは追記したいと思います。誰かのお役に立てば嬉しいです。

またね。

この記事を書いた人

ハロ

ハロ

学究の兎です。コンピュータサイエンス全般が好きで、ある時はハンダごてを握って電子回路を作ってみたり、またある時は新しいプログラミング言語を覚えて嬉々としてキーボードを叩いていたりします。