Initializing variable/class question.

int var1 = 3;
anObject instace1(5);

void startup(void) {

  bla..
  bla..
}


void loop(void) {

   bla...
}

I've used the int var1 = 3; outside of any function and not found an issue with it.

But I've seen where anObject instace1(5); declared and initialzed outside of any functions has caused issues.

Is there any c++ rule about this? Because although it compiles, I get the idea the result could be somewhat undefined.

Anyone know?

Thanks!

-jim lee

Read about Constructors --> Constructors and member initializer lists - cppreference.com

A constructor is a kind of member function that initializes an instance of its class. A constructor has the same name as the class and no return value. A constructor can have any number of parameters and a class may have any number of overloaded constructors. Constructors may have any accessibility, public, protected or private. If you don't define any constructors, the compiler will generate a default constructor that takes no parameters

No no no, you miss the point of my question. I know what a constructor is.

My question is : When declaring a global instance of a class outside of any function using a constructor that uses passed in parameters. I seem to remember that this wasn't allowed in earlier Arduino IDEs and now it is allowed. But it seems to me like it doesn't always work correctly.

Does anyone know about this?

-jim lee

When declaring a global instance of a class outside of any function using a constructor that uses passed in parameters. I seem to remember that this wasn't allowed in earlier Arduino IDEs

Nonsense. Constructors with arguments have always been allowed.

It is stupid to call a class anObject. An instance of the class, maybe. NOT the class.

So, post your REAL code, and we can talk about some real code (and problems). This isn't the hand-waving forum.

It's a standard C++ thingy - always worked

If it did not for you then it's the class constructor was buggy..

What may not work in Arduino is using pinMode and other initialization functions in the constructor,
because it may run before the systems init() function.
For these functions a begin(...) function should be used.
So you could pass in the pin number in the constructor, but move the pins pinMode into the begin function.

Foud the problem. It was confusion between passing in a pointer that was interpreted as a value. Turns out you can't have word & pointer overloaded methods as they look the same to the compiler.

And PaulS, I know your time must be valuable. So please, don't feel obligated to participate on my topics in the future.

-jim lee

PaulS is correct. You may ignore his advice but you do so at your own peril.

Whandall:
What may not work in Arduino is using pinMode and other initialization functions in the constructor,
because it may run before the systems init() function.
For these functions a begin(...) function should be used.
So you could pass in the pin number in the constructor, but move the pins pinMode into the begin function.

This seem to be another mixed up / concocted Arduino ways to explain things.
Mixing apples with oranges .
The class is constructed by , what else - a constructor. The variables passed to class via constructor are just variables and there is nothing special about hardware AKA pins variables. The init and begin are just another class functions, nothing to do with system, and generally used to initialize (other ) variables not passed to the class.
I have mentioned this before , but "begin" is poor choice for function / method whose job is to initialize things. But it's an Open source so anybody can name their function the way they like.

One advantage of processing variables outside constructor - the processing function can return values to the calling process, constructor cannot.

Jim

jimLee:
No no no, you miss the point of my question. I know what a constructor is.

My question is : When declaring a global instance of a class outside of any function using a constructor that uses passed in parameters. I seem to remember that this wasn't allowed in earlier Arduino IDEs and now it is allowed. But it seems to me like it doesn't always work correctly.

Does anyone know about this?

-jim lee

Something like this strange syntax?

IDE_USBHost::IDE_USBHost() : bmHubPre(0)

I don't mean to hijack the thread - but I have been struggling with making an instance of "top" class in an inheritance scheme and pass variables to each of the underlining classes using this syntax. Major pain to test.

Globals are initialized before 'main' is called and it is in 'main' the Adrudio hardware is initialized potentially undoing hardware setup in a constructor.

I agree 'begin()' is not the best of names but wasn't the API developed by an Italian?

julyjim:
IDE_USBHost::IDE_USBHost() : bmHubPre(0)

I don't mean to hijack the thread - but I have been struggling with making an instance of "top" class in an inheritance scheme and pass variables to each of the underlining classes using this syntax. Major pain to test.

Meh - this syntax works perfectly fine. The main benefit of it is that it allows you to initialize const variables.

As other people have noted, the main no-no is attempting to talk to hardware (eg: using pinMode()) in constructors. When doing C++ for the arduino, I give everything a setup() and a loop() even if those methods are empty. Sure, it wastes a couple of cycles. But keeping that design consistent makes programming easier.

Main thing here on this forum is that the only possible reply to

But I've seen where anObject instace1(5); declared and initialzed outside of any functions has caused issues.

is "wat?". What "issues"? I mean - the compiler and the language does what it does, it's well-defined what will happen. The only possible "issue" is the programmer not having a thorough understanding of what that is.

This, perhaps, is why PaulS got a bit snippy. Loved your reply, though.

Oh, other reason: generally, classes and types use CamelCase with initial caps, and variables (instances) use camelCase with an inital lowercase. ALL_CAPS is for #defines and possibly for const variables. Calling a class anObject is going to get right up people's noses for that reason.

I personally tend to use snake_case for private or local variables, but that's personal preference. snake_case is a more old-school C thing, whereas camelCase is more object-y and java-ish. In my code, snake_case is a signal that something low level that is "plain" C is going down.

This seem to be another mixed up / concocted Arduino ways to explain things.

It is, nevertheless, the closest to "correct" WRT discussing the limitation so constructors with Arduino sketches.
You should be able to initialize object variables with a constructor, but are likely to run into problems if you try to do anything with the Arduino hardware... And "xxx.begin()" is the defacto standard for getting around the problem.

I have mentioned this before , but "begin" is poor choice for function / method whose job is to initialize things.

It is, however, a convention. Of course, you are free to name your init() method whatever you like, as long as the name clearly reflects what the function does.

I just want to agree that the code snippet is poor, and the description is worse. I spent decades answering questions of the form: "The compiler issued an error message and now my program doesn't work", which often boiled down to a linker error message resulting in no executable being produced. So, some older version ran.

There is no such thing as "issues". There is no such thing as "an error message". There are specific problem associated with specific code, and there are specific error messages that have actual text. No diagnosis can be done unless the specific issues are discussed, along with the specific code that caused them. If you need to reproduce the problem in a way that doesn't involve hundreds of lines of code, create the same, identical behavior in a tiny program, preferably with as few lines as possible, to demonstrate the problem.

Be aware that constructors execute in an undefined order, so if your constructor is based on the assumption that another class's constructor has run, you are out of luck. C++ does not guarantee constructor order, and if you deduce it empirically, it could change on your next compilation (seriously; this is not the result of a random number generator, but based on how the linker assembles your modules, which can change if you change your program in any way that forces a change in linker order, which is very, very, very easy to do. Hence the use of the phrase "undefined"). Any given constructor cannot depend on the completion of any other constructor. Often, this interdependency exists, and is characterized by a global assumption that constructors do not work. Yes, they work, and they work as expected, but "expected" means "consistent with the C++ language standard" and not "consistent with how I want them to work".

In the absence of an adequate description, it is impossible to help. For example, maybe the OP can help me. My program doesn't work. What did I do wrong?
joe

if you try to do anything with the Arduino hardware...

That is one of the primary "issues" , common to many posts on this forum.
Users just do not relate to that software and hardware work together.
Pushing a button to make LED blink, display characters on LCD... just few examples.

It reminds me of a work incident I had when my supervisor got exited because while I was building a hardware lab setup, stringing wires , I was also using software.
Good old days of VB.

Jim