complicated #define

Hello, I am very newbe in programming Arduino or C++ language.
Before posting this forum, I deeply searched into the web but I haven't found nothing that explains this strange DEFINE.
I am working on a CANBUS interface and used the Sparkfun shield code on an Arduino Mega 2560, about 90% of the sketch is clear for me, this is not.
Here the piece of code

   //Definitions for SD card
  // store error strings in flash to save RAM
#define error(s) error_P(PSTR(s))

I read that PROGMEM should deal with the flash storing strings in that memory area.

The sub:

void error_P(const char* str) {
   PgmPrint("error: ");
   SerialPrintln_P(str);
//
   Serial.print("SD error");
//
   if (card.errorCode()) {
     PgmPrint("SD error: ");
     Serial.print(card.errorCode(), HEX);
//
     Serial.print(',');
     Serial.println(card.errorData(), HEX);
//
   }
   while(1);
 }

And obviously we have some error strings:

 //************************* SD CARD SETUP *******************
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  // breadboards.  use SPI_FULL_SPEED for better performance.
  if (!card.init(SPI_FULL_SPEED,SD_PIN)) error("card.init failed");

  // initialize a FAT volume
  if (!volume.init(&card)) error("volume.init failed");

  // open the root directory
  if (!root.openRoot(&volume)) error("openRoot failed");

The central question is: what does it means when a constant is defined like "error(s)"?
So please can someone shed a little light on this?
Thanks for your help.
regards
Alessandro

alex998r:
The central question is: what does it means when a constant is defined like "error(s)"?
So please can someone shed a little light on this?

The variable name in round brackets is something similar like a "parameter" in a function declaration.

So in your #define statement "error(s)" is expanded to "error_P(PSTR(s))", where 's' is the parameter.

jurs is correct, this is an example of what is called a parameterized macro where the s within the parentheses is the data being passed to the macro. One useful macro I often use is:

#define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0]))

So if your code has an array named myArray[] define with, say, 10 elements, you often see code like:

for (i = 0; i < 10; i++) {
   temp - myArray[i];
   // more code...
}

However, if you change the size of myArray[], now you have to use an error-prone search-and-replace process to get rid on the magic number 10. However, if instead you write:

for (i = 0; i < ARRAYSIZE(myArray); i++) {
   temp - myArray[i];
   // more code...
}

all you have to do is recompile the program after you change the array size. Parameterized macros can simplify things considerably.

Hi guys, thanks a lot for your kind help, now is more clear, I will do some tests.