How is the RC 522 object being initialized?

In a popular RFID library it seems that the main object used to abstract the RC 522 hardware device is initialized in an unusual (for me) way. The code, abridged, generally looks like this in all the example sketches:

01  #include <MFRC522.h>
02  
03  #define SS_PIN 10
04  #define RST_PIN 9
05  MFRC522 mfrc522(SS_PIN, RST_PIN);
06  
07  void setup() {
08      mfrc522.PCD_Init();
09  }

I'm far more versed in Python than C, so I'm a bit confused about what is going on here. As we can see on line 08, there is an object with the identifier "mfrc522", on which the "PCD_Init()" method is being invoked. But the line which seems to initialize the object with identifier "mfrc522", line 05, looks like it is calling some function called "mfrc522", not like it is declaring an object with the identifier "mfrc522". What is going on here?

I've tried searching the fine internet for information on this syntax, but not knowing what it is called I can find no information. So what is this syntax called, and where can I read more about what is going on?

Thank you.

Its the object's initializer, universal in C++, you can use it for int variables too if you really want:

int foo(6);  // works exactly like:
int bar = 6;

The object is declared, space allocated statically for it, and the constructor called with the initializer's argument list. Usually the syntax is only used with objects though.

You'll see this everywhere in every C++ program - time to read an intro to C++ I think.

The method PCD_Init() is called in setup() as constructors for static variables are called too early on, nothing
is guaranteed to work at that stage except static memory allocation and setting instance variable values.

https://en.cppreference.com/w/cpp/language/initialization

I see, thank you. You are correct about my lack of C++, I've only ever concentrated on C before discovering the Arduino. I'll be sure to take care of that!

So if I understand correctly, these two lines are functionally identical?

MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522 mfrc522 = MFRC522(SS_PIN, RST_PIN);

Thank you.

There are others on the forum more versed in these nuances than I. But, I think the second method may unnecessarily invoke the Copy Constructor.

dotancohen:
I see, thank you. You are correct about my lack of C++, I've only ever concentrated on C before discovering the Arduino. I'll be sure to take care of that!

So if I understand correctly, these two lines are functionally identical?

MFRC522 mfrc522(SS_PIN, RST_PIN);

MFRC522 mfrc522 = MFRC522(SS_PIN, RST_PIN);




Thank you.

Yeah, those two are functionally identical because the compiler optimizes the second statement to be the same as the first one.

arduino_new:
Yeah, those two are functionally identical because the compiler optimizes the second statement to be the same as the first one.

I see, thank you. An important detail to note, for myself or others seeing the syntax for the first time, is that this form only works when providing constructor arguments. Without arguments this form looks to the compiler as a function signature declaration.

Now knowing to search for "C++ object initializer", I've since found this post which explains the nuances:

dotancohen:
I see, thank you. An important detail to note, for myself or others seeing the syntax for the first time, is that this form only works when providing constructor arguments. Without arguments this form looks to the compiler as a function signature declaration.

Yes. This is an object declaration:

ObjectClass objectInstance(1);

But this is a function prototype for a function taking no arguments and returning an object of type ObjectClass:

ObjectClass function();

If the constructor takes no arguments, leave out the parens:

ObjectClass objectInstance;