uniform initialisation, object oriented programming etc.

Status
Not open for further replies.

frankzappa

Well-known member
Hello!

I'm learning C++ and I've just started the chapter on OOP, classes, constructors etc. There is something called "member initialisation list" where you can use direct or uniform initialisation to initialise an object with constexpr members. Constexpr variables are tricky because you can't assign a value to them, you can only initialise them so you have to use an initialisation list as far as I understand.

My question is, does this work in the Arduino IDE? I can't seem to get it to work. In fact uniform initialisation doesn't seem to work. Is there a different syntax for this in arduino? I can use for example int x = {0}; but int x{0}; doesn't seem to work.

Also It seems you can zero initialise an array without using a for loop but again I haven't been able to do it in arduino.

Is there any difference between the three types of initialisation?
 
My question is, does this work in the Arduino IDE?

Yes, works great.

Code:
class myclass {
  public:
  constexpr myclass() : myvariable(10000) {}
  int myvariable;
  int increment() { return ++myvariable; }
};

myclass myinstance;

void setup() {
}

void loop() {
  Serial.println(myinstance.increment());
  delay(100);
}

We also use constexpr constructors in some of the main classes, like Arduino Print.

https://github.com/PaulStoffregen/c...108f7242967e0dadbc41b34bc/teensy4/Print.h#L57
 
Yes, works great.

Code:
class myclass {
  public:
  constexpr myclass() : myvariable(10000) {}
  int myvariable;
  int increment() { return ++myvariable; }
};


myclass myinstance;

void setup() {
}

void loop() {
  Serial.println(myinstance.increment());
  delay(100);
}

We also use constexpr constructors in some of the main classes, like Arduino Print.

https://github.com/PaulStoffregen/c...108f7242967e0dadbc41b34bc/teensy4/Print.h#L57

Wait, now you made the constructor constexpr. What does that do? It was not what I meant. I'm simply trying to create a constexpr member inside the class. It seems I can't do that.

Here is an example:
This works:
Code:
class Something
{
private:
    const int m_array[5];
 
public:
    Something(): m_array { 1, 2, 3, 4, 5 } // use uniform initialization to initialize our member array
    {
    }
 
};

This does not:

Code:
class Something
{
private:
    constexpr int m_array[5];
 
public:
    Something(): m_array { 1, 2, 3, 4, 5 } // use uniform initialization to initialize our member array
    {
    }
 
};

How can I create a constexpr member?
 
Maybe this can help?

https://stackoverflow.com/questions/27408819/why-cant-non-static-data-members-be-constexpr


On Teensy we are using "gnu++14" dialect, which is C++14 with GNU's extensions. As far as I know, it fully supports all C++14 features. But I will admit, I'm not a C++ expert. I personally tend to use only a subset of C++ features, so I'm not very familiar with the stuff outside of that subset. Regarding your original question of what works, or at least should work, in Arduino using Teensy, the answer is everything which the C++14 standard allows is supposed to work.

Regarding your question "How can I create a constexpr member?", I'm afraid I can't really answer that. It's not a way I have personally ever used C++. Info online, like that Stack Overflow question, seems to say it's only allowed by the C++ standard if the variable is static.

I believe there is a distinction to be drawn between something not working because Arduino & the gcc toolchain we use doesn't support it, versus that thing not being valid C++14 code which could not be expected to compile or work on *any* standards compliant C++ compiler.

If you have some intended purpose behind these questions, beyond just playing with the semantics of C++ language, maybe explaining the context of what you're really trying to accomplish would allow me and others to better help. As this thread exists so far, it really doesn't make any sense to me, apart from implying that Arduino isn't supporting some particular C++ feature.
 
I'll quickly try to answer just one more question. I'm afraid this may be the last I answer on this thread. Maybe others more familiar with C++ features might jump in?

Wait, now you made the constructor constexpr. What does that do?

It means all the member variables must have compile time initialization. Like all C++ features, I'm sure you can find a lot of info online.

As a practical matter, we've seen the compiler is often much better at optimizing the compiled code when classes use constexpr constructors.
 
Maybe this can help?

https://stackoverflow.com/questions/27408819/why-cant-non-static-data-members-be-constexpr


On Teensy we are using "gnu++14" dialect, which is C++14 with GNU's extensions. As far as I know, it fully supports all C++14 features. But I will admit, I'm not a C++ expert. I personally tend to use only a subset of C++ features, so I'm not very familiar with the stuff outside of that subset. Regarding your original question of what works, or at least should work, in Arduino using Teensy, the answer is everything which the C++14 standard allows is supposed to work.

Regarding your question "How can I create a constexpr member?", I'm afraid I can't really answer that. It's not a way I have personally ever used C++. Info online, like that Stack Overflow question, seems to say it's only allowed by the C++ standard if the variable is static.

I believe there is a distinction to be drawn between something not working because Arduino & the gcc toolchain we use doesn't support it, versus that thing not being valid C++14 code which could not be expected to compile or work on *any* standards compliant C++ compiler.

If you have some intended purpose behind these questions, beyond just playing with the semantics of C++ language, maybe explaining the context of what you're really trying to accomplish would allow me and others to better help. As this thread exists so far, it really doesn't make any sense to me, apart from implying that Arduino isn't supporting some particular C++ feature.

It's just me trying to learn, it's not allowed in C++ it seems.

I'm trying to create members that I want to be resolved at compile time. It's not a problem, I can just create them as variables outside the class. I thought it could be done somehow but I saw now that it is not possible.
 
I'll quickly try to answer just one more question. I'm afraid this may be the last I answer on this thread. Maybe others more familiar with C++ features might jump in?



It means all the member variables must have compile time initialization. Like all C++ features, I'm sure you can find a lot of info online.

As a practical matter, we've seen the compiler is often much better at optimizing the compiled code when classes use constexpr constructors.

Thanks for that tip.
 
A slightly related thing I came up with. At first the "case function" doesn't look legal.

Code:
constexpr unsigned hash(const char *string)
{
 return *string == 0 ? 17325 : *string + (*string * hash(string+1));
}

...

switch (hash(string)) 
{
   case hash("command"):
       .....
 
Status
Not open for further replies.
Back
Top