ifconfig
ifconfig

Reputation: 6832

Unexpected compilation errors experienced with Arduino code under vscode

I have been trying to get the Arduino extension for vscode working reliably for a little while now. A stripped-down version of the sketch that produces the issue is as follows:

// Object to store read CPPM values
struct CPPMFrame {
  // Analog sticks (values -1000 to 1000)
  int pitch = 0;
  int roll = 0;
  int thr = 0;
  int yaw = 0;

  // Switches/dials (values -1000 to 1000, usually -1000, 0, or 1000)
  int aux1 = 0;
  int aux2 = 0;
};

void readCPPM(CPPMFrame* frame) {
  //...
}

void setup() {//...}

void loop() {//...}

When "verified" with F1+Arduino: Verify, the following is produced in the Output window:

[Starting] Verify sketch - Joystick.ino
[Warning] Output path is not specified. Unable to reuse previously compiled files. Verify could be slow. See README.
Loading configuration...
Initializing packages...
Preparing boards...
Verifying...
Joystick:14:15: error: variable or field 'readCPPM' declared void

 void readCPPM(CPPMFrame* frame) {

               ^

Joystick:14:15: error: 'CPPMFrame' was not declared in this scope

Joystick:14:26: error: 'frame' was not declared in this scope

 void readCPPM(CPPMFrame* frame) {

                          ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-JoystickTest.ino: In function 'void setup()':

Debug-JoystickTest:170:6: error: redefinition of 'void setup()'

 void setup() {

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-CPPM-Monitor.ino:37:6: note: 'void setup()' previously defined here

 void setup()

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-JoystickTest.ino: In function 'void loop()':

Debug-JoystickTest:195:6: error: redefinition of 'void loop()'

 void loop() {

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-CPPM-Monitor.ino:44:6: note: 'void loop()' previously defined here

 void loop()

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Joystick.ino: In function 'void setup()':

Joystick:18:6: error: redefinition of 'void setup()'

 void setup() {}

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-CPPM-Monitor.ino:37:6: note: 'void setup()' previously defined here

 void setup()

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Joystick.ino: In function 'void loop()':

Joystick:20:6: error: redefinition of 'void loop()'

 void loop() {}

      ^

c:\Users\neilb\Documents\GitHub\Arduino-CPPM-Adapter\Debug-CPPM-Monitor.ino:44:6: note: 'void loop()' previously defined here

 void loop()

      ^

exit status 1
[Error] Exit with code=1

None of these errors or warnings are produced by Arduino IDE 1.8.7, where it verifies perfectly. I'm not sure if it'll be of any use, but here is my arduino.json and c_cpp_properties.json.

./vscode/arduino.json:

{
    "board": "arduino:avr:micro",
    "sketch": "Joystick.ino"
}

./vscode/c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "C:\\Program Files (x86)\\Arduino\\tools\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\**",
                "C:\\Users\\neilb\\Documents\\Arduino\\libraries\\CPPM",
                "C:\\Users\\neilb\\Documents\\Arduino\\libraries\\Joystick"
            ],
            "forcedInclude": [
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
            ],
            "intelliSenseMode": "msvc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

What is happening here?

Upvotes: 1

Views: 1087

Answers (1)

hlovdal
hlovdal

Reputation: 28180

You seem to have two problems, one that both JoystickTest.ino and CPPM-Monitor.ino are compiled at the same time which this answer does not dive into further, and the compile error

Joystick:14:15: error: variable or field 'readCPPM' declared void
void readCPPM(CPPMFrame* frame) {

Joystick:14:15: error: 'CPPMFrame' was not declared in this scope
Joystick:14:26: error: 'frame' was not declared in this scope
void readCPPM(CPPMFrame* frame) {

This looks like Arduino's special prototype handling. Normally in C and C++ if you try to use a function before its prototype has been declared you will get an compiler error. In order to make Arduino more newbie friendly when compiling it first scans the source file to only make a list of functions so that you can call a function in setup even if it is defined later in the file. This works fine when the functions only have basic types like int, char * etc but fails if you use enums, structs etc because the compiler does not have parsed those at that point.

The short term remedy is to force an explicit prototype generation, e.g. you can put one right in front:

void readCPPM(CPPMFrame* frame);
void readCPPM(CPPMFrame* frame) {
...

although long term you are much better off not stuffing everything into the main ino file but instead put this code into separate source files with corresponding header files which then avoids the issue entirely.

Upvotes: 1

Related Questions