Arduino IDE compiler not recognising custom struct

Hello,

I'm having an issue that seems to be a direct error of the arduino compiler more than my direct code, and I don't know how to fix it.

Effectively, for no reason whatsoever, the compiler will fail to find a struct I've defined for some functions, but not others, and it seems entirely random. My code is split across 3 files, but the core issue is file number 2:

#include <cmath>
#include <LinkedList.h>

struct Vector2 { float x,y; };

float getDistance(Vector2 point1, Vector2 point2) {
  return sqrt(
    pow(point1.x - point2.x, 2) +
    pow(point1.y - point2.y, 2)
  );
}

LinkedList<Vector2> createLineDefinition(Vector2 pointA, Vector2 pointB, int dotsBudget) {
  LinkedList<Vector2> result = LinkedList<Vector2>();
  for(int i = 0; i < dotsBudget; i++) {
    Vector2 point;
    float perc = float(i)/float(dotsBudget-1);

    point.x = pointA.x + (pointB.x-pointA.x)*perc;
    point.y = pointA.y + (pointB.y-pointA.y)*perc;

    result.add(point);
  }
  
  return result;
}

LinkedList<Vector2> createShape(LinkedList<Vector2> points, int dotsBudget) {
  float perimeter = 0;
  for (int i = 0; i < points.size()-1; i++) {
    perimeter += sqrt(pow(points[i].x - points[i+1].x, 2) + pow(points[i].y - points[i+1].y, 2));
  }

  LinkedList<Vector2> result = LinkedList<Vector2>();
  int dotsUsedTotal = 0;
  for (int i = 1; i < points.size(); i++) {
    int dotsAllowed = dotsBudget * (sqrt(pow(points[i].x - points[i-1].x, 2) + pow(points[i].y - points[i-1].y, 2))/perimeter);
    dotsUsedTotal += dotsAllowed;

    LinkedList<Vector2> tmp = createLineDefinition(points[i-1],points[i],dotsAllowed);
    for (int x = 0; x < tmp.size(); x++) {
      result.add(tmp[i]);
    }
  }

  // Dot corrector
  for(int i = 0; i < dotsBudget - dotsUsedTotal; i++) {
    result.add(result.get(result.size() - 1));
  }

  return result;
}

For some reason, while functions "createShape" and "createLineDefinition" are totally 100% happy and compile just fine, "getDistance" throws a "Compilation error: 'Vector2' was not declared in this scope" error, and I can't for the life of me understand why. It's literally the exact same variable that compiles happily for the other 2 functions, but for some reason "getDistance" and another function later on "addDataToCurrentBuffers" seem to throw this same error for some reason. The only link I can see is that functions returning a LinkedList seem happy, but void functions and float functions fail for some reason.

This is truely perplexing to me, and I've tried taking into account the order of compilation and the way the compiler scans the file for linking variable types, but it just seems entirely random to me.

Using Arduino IDE 2.2.1. Tried restarting Arduino IDE, no difference still complains. Specifically the error is:

C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:3:19: error: 'Vector2' was not declared in this scope
    3 | float getDistance(Vector2 point1, Vector2 point2) {
      |                   ^~~~~~~
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:3:35: error: 'Vector2' was not declared in this scope
    3 | float getDistance(Vector2 point1, Vector2 point2) {
      |                                   ^~~~~~~
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:3:49: error: expression list treated as compound expression in initializer [-fpermissive]
    3 | float getDistance(Vector2 point1, Vector2 point2) {
      |                                                 ^
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:59:40: error: 'Vector2' was not declared in this scope
   59 | void addDataToCurrentBuffer(LinkedList<Vector2> points) {
      |                                        ^~~~~~~
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:59:47: error: template argument 1 is invalid
   59 | void addDataToCurrentBuffer(LinkedList<Vector2> points) {
      |                                               ^
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:3:49: error: 'float getDistance(Vector2, Vector2)' redeclared as different kind of entity
    3 | float getDistance(Vector2 point1, Vector2 point2) {
      |                                                 ^
C:\Users\aj200\Documents\GitHub\My-Projects\Active Projects\ESP32_Renderer\Rendering_Engine.ino:3:7: note: previous declaration 'float getDistance'
    3 | float getDistance(Vector2 point1, Vector2 point2) {
      |       ^~~~~~~~~~~

exit status 1

Compilation error: 'Vector2' was not declared in this scope

Kind regards,
Andrey

This is usually caused by the auto-generation of function prototypes by the IDE, where the function prototype gets placed before the definition of the struct. Putting your own function prototype in the code will correct the problem.

While you're at it, why not pass those Vector2 parameters into the functions by const references rather than by value?

I did try putting my own prototype, but it didn't do anything which was super odd?

Where did you place the function prototype? It must be after the struct is declared.

Part of the problem may be that you have the code split into three files.

Ok, I've got it to compile now.... but I still don't understand what was wrong. I compressed all my code from multiple files into the singular main .ino file, and with some moving things around it compiles now, but I'm still super confused why it wasn't before. I even tried using a prototype like david_2018 suggested, but still wouldn't.

I don't know why arduino IDE insists on making file splitting like this super complicated. Literally every single time without fail, if I try to neaten my code by using supplimentary .ino files in the same folder, they ALWAYS go wrong somehow, and it's always with some kind of linking glitch like this. Why is this an issue?

I've compiled code for windows and ubuntu in c++ using the MinGW GCC compiler directly off commandline and had easier time than the arduino IDE with code across multiple files. Is there a way to compile for an ESP32 using the GCC compiler directly instead if it's gonna be this painful? Like is it a arduino compiler issue, or some kinda of arduino IDE/ESP32 compiler incompatibility? Because I've had this same linking glitch with other boards like Uno and Mega2560s as well. It's something wonky with the compiler being unable to link things together or look ahead to understand what's going on. It seems to just directly read the code top to bottom while compiling

Too bad you didn't post your complete code. Do you expect us to guess?

If I dump my whole code, people get mad because "You didn't simplify it down to display the issue". Made that mistake before.

You need to understand the order in which the files are handled.

The IDE takes the main file, which is the file with the same name as the sketch folder, then appends the remaining .ino files in alphabetical order (I'm assuming using the same rules for alphabetical order that the file system uses). This is done before any compilation takes place, so it can end up placing your function prototype after the first call to the function.

That... makes sense why I was having so many issues. Alphabetical order? I assumed it linked the files in the order the tabs were open in the IDE, which would have made it all make sense. But if it's loading the files in alphabetical order, then yes my code would have loaded all jumbled up. File names like "Rendering_Engine", "Example_Shapes", and "Main_Processing" would have been the issue then. I'll keep that in mind for next time I'm doing a project like this. I assume a simple solution would be to name the files starting with numbers, or AA_ then AB_ and so forth so I know it's in order?

Or you could do it the right way and create a proper .h / .cpp file structure per My Post #5 in this Thread.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.