Running c programs with arduino

Hello! I was wondering if I can use c code in arduino for more complex programs. I have read that yes, you can run c code here.
But when I try to run my program I get a lot of compile errors. I am using a simulator (my arduino got broken recently) and this may be causing the problem.
This is the program i am trying to run (it is basically a linked list test) :slight_smile: :

#include stdlib.h

typedef struct {
int dato;
struct data *next;
struct data *prev;
} data;

void addLast(data **last){
data *nuevo = malloc(sizeof(data));
nuevo->dato = (*last)->dato + 1;
nuevo->prev = *last;
(*last)->next = nuevo;
*last = nuevo;
}

void addFirst(data **first){
data *nuevo = malloc(sizeof(data));
nuevo->dato = (*first)->dato-1;
nuevo->next = *first;
*first = nuevo;
}

void printlist(data* first){
data *current = first;
while(current != NULL){
Serial.print(" ");
Serial.print(current->dato);
current = current->next;
}

}
void setup() {
data *nuevo = malloc(sizeof(data));
nuevo->dato = 0;
data *first = nuevo;
data *last = nuevo;
for(int i = 0; i < 10; i++){
addLast(&last);
addFirst(&first);
}
Serial.begin(9600);
printlist(first);
}
void loop(){
;
}

I just want to know if this is possible or not

Yes, it is possible. You will need to fix the #include format and any other errors that will arise.

how would you write the include? I had to remove the triangle thing because it would get removed when publishing the post, is that what you are referring to?
the rest of the code is correct, it compiles perfectly on my pc...
So i guess its a problem of the simulator

You have to put things in the proper order and you don't need that include

struct data {
  int dato;
  struct data *next;
  struct data *prev;
};

void addLast(data **last) {
  data *nuevo = (data *)malloc(sizeof(data));
  nuevo->dato = (*last)->dato + 1;
  nuevo->prev = *last;
  (*last)->next = nuevo;
  *last = nuevo;
}

void addFirst(data **first) {
  data *nuevo = (data *)malloc(sizeof(data));
  nuevo->dato = (*first)->dato - 1;
  nuevo->next = *first;
  *first = nuevo;
}

void printlist(data * first) {
  data *current = first;
  while (current != NULL) {
    Serial.print(" ");
    Serial.print(current->dato);
    current = current->next;
  }

}
void setup() {
  data *nuevo = (data *)malloc(sizeof(data));
  nuevo->dato = 0;
  data *first = nuevo;
  data *last = nuevo;
  for (int i = 0; i < 10; i++) {
    addLast(&last);
    addFirst(&first);
  }
  Serial.begin(9600);
  printlist(first);
}
void loop() {
  ;
}
1 Like
typedef struct {
int dato;
struct data *next;
struct data *prev;
} data;

The big problem is here. You have "struct data *next", but you haven't defined a "struct data" type; you've only have a full "data" typedef. Of course, that typedef isn't complete here where you need it...

For self-referential structs like this, the problem is frequently solved like:

typedef struct data_ {
  int dato;
  struct data_ *next;
  struct data_ *prev;
} data;

I didn't know about that, thank you (it seems like a much better way to do it). However, the program perfectly compiles and executes with gcc on my computer... I'm pretty sure the problem I'm facing is just that the simulator I'm using doesn't work properly

What do you mean by "put things in the proper order"? You didn't modify anything into that code

Hi @tremon_36. Please use code blocks when posting code, compiler output, error messages, etc. to the forum. You can do that by following these instructions:

  1. Paste the code into the forum's post editor field, just like usual.
  2. Select all the code in the editor field.
  3. From the toolbar at the top of the editor field, click the </> button

If your browser doesn't show that forum editor toolbar or you prefer to format your post manually, you can use the Markdown markup language (or BBCode if you prefer):
https://www.markdownguide.org/extended-syntax/#fenced-code-blocks
Just add three backticks (```) on the line before and after the code:

```
void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}
```

Some of your problems may be due to .ino files being compiled with a C++ compiler, rather than C. For the most part, C++ is a superset of C and it should work OK, but there are some subtle differences.

The one that stands out is:
data *nuevo = malloc(sizeof(data));
I believe that would be legal in C - malloc() returns a void* pointer, and C lets you assign a void* to any other pointer. C++, however, insists upon having a cast to the actual type:
data *nuevo = (data *)malloc(sizeof(data));
(that would be legal in pure C as well.)

I'm not sure whether the self-referential struct problem is a similar C++ issue, or whether it's due to the automatic prototyping that Arduino does on .ino files...

To do PURE C programming, put your code in a separate .c tab, and call it from your
setup() function:
extern "C" void cmain();
void setup() {
cmain();
}

I most certainly did modify the code you posted. You had this

    typedef struct {
      int dato;
      struct data *next;
      struct data *prev;
    } data;

Which is a type definition of an anonymous struct. And I did

    struct data {
      int dato;
      struct data *next;
      struct data *prev;
    };

Which is just a struct named 'data' but since you are using a C++ compiler, you do not need to use the word 'struct' in other places so just using 'data' works.

It is very similar to what westfw posted

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