Can you use main() in a regular Arduino program?

On another forum someone says they used the following program with the Arduino IDE and that it compiled and uploaded properly:

/*
    5-10-07
    Copyright Spark Fun Electronics© 2007
    Nathan Seidle
    nathan at sparkfun.com
   
    ATmega168
   
   Example Blink
   Toggles all IO pins at 1Hz
*/

#include <avr/io.h>

//Define functions
//======================
void ioinit(void);      //Initializes IO
void delay_ms(uint16_t x); //General purpose delay
//======================

int main (void)
{
    ioinit(); //Setup IO pins and defaults

    while(1)
    {
      PORTC = 0xFF;
      PORTB = 0xFF;
      PORTD = 0xFF;
      delay_ms(500);

      PORTC = 0x00;
      PORTB = 0x00;
      PORTD = 0x00;
      delay_ms(500);
    }
   
    return(0);
}

void ioinit (void)
{
    //1 = output, 0 = input
    DDRB = 0b11111111; //All outputs
    DDRC = 0b11111111; //All outputs
    DDRD = 0b11111110; //PORTD (RX on PD0)
}

//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
      for ( z = 0 ; z < 6 ; z++){
        asm volatile ("nop");
      }
    }
  }
}

I responded that this won't work because it has the main() function in it and would cause the Arduino IDE to generate this error:

In function 'int main()':
error: redefinition of 'int main()"

To which the person responded:

As far as I'm aware, it only adds it the main() function if there isn't one present: e.g. it will make up for a number of mistakes only if they are present.

Am I missing something fundamental? I don't think so, but I thought I'd check here first.

Smiley

You win this round. I copied and pasted the code into the IDE (17), and got exactly the error message you described.

The fellow said he was using Arduino 0018, so I just tried it and it works. I posted the following:

Holy Poop! It does compile in Arduino 0018.

This is not a quibble because it doesn't compile in earlier versions and this is major news to me. I need to investigate this further, but if the Arduino has done away with their earlier way of doing things such that regular C code compiles okay, then I'm in deep doo for reasons irrelevant to this thread. I know this isn't your issue, but tomorrow I'll try to see how this uploads and behaves on my Arduino and maybe I can help you with the specific issues you mention.

BTW - I've seen your error messages before when I didn't properly sync pressing the reset button with starting AVRDude. What I do is get the AVRDude script ready to run, press the reset button on the Arduino then immediately hit the return button to run AVRDude. The Arduino board sends a pulse on the DTR line to reset the Arduino just before it calls AVRDude so that happens automatically, but since you are building your own board, you'll need to do your own reset.

Sorry, for the confusion.

Smiley

I hope somebody here knows more about this. It seems I've missed a big issue.

Smiley

Hi,
sometimes I am really surprised how creative are people in misusing tools/software/whatever. :sunglasses:

Ok, there is a little problem with this. Replacing/overwriting main() has a few sideeffects. The Timers-functions (PWM)/Analog RW and HardwareSerial provided by the Arduino-code are not initialzed. Put a normal delay(1000) call into the sketch-code and it will stop working at this point.
The setup() and loop() functions are also not called automatically any more.

So, it compiles but isn't of much use.

Eberhard

1 Like

There are many non-Arduino programs made for ATmega architecture (no setup, no loop, just a main) that I would like to use in the Arduino IDE. Being able to replace the built-in main() is a good thing, but as noted, there are some minor issues.

As I recall, the built-in main() is just this:

void main() {
    init();
    setup();
    while (1)
        loop();
}

So if you wanted to support Arduino library features like delay(), but don't have the setup/loop structure in your ATmega project, you have two options:

(1) call the built-in init() in your main() before you use Arduino library features, or

(2) change your main() to be called setup() and provide a dead, empty loop() function.

Okay, finally got the word from the horse's mouth.

This is an accident and not a feature of Arduino.

From David Mellis:
Quote:

The reason it's not supported is because it might change. It
happened as accidental by-product of other changes and could disappear
in the same way.

This means that if you are going to use the Arduino you should only use code in the Arduino format. That is no main() function and you use setup() and loop() instead. The main function is added to your code and has an ioinit() function before calling setup() and loop(). If you use this accidental bypass then the Arduino ioinit() won't get called and the Arduino library functions might mess up in unpredictable way.

Bottom line:

  1. Don't use code with the int main(void) function in it.
  2. Do read the Arduino introductory materials.
  3. Only use code in the Arduino Sketch format.

Smiley