the `.move()` function does not work as expected. The motors does not move a bit. I believe that the `extern test` creates an empty class. I think this is because of the alphabetical order the compiler compiles things. If I rename h.cpp to j.cpp(which is alphabetically after initialize), it works perfectly fine. Is there a way to work around this or do the h.cpp file should be alphabetically after all other cpp files? I tried changing the name of the config.h file but it doesn't matter.
Edit:For you info, here is core.h and core.cpp
//core.cpp
#include "globals.h"
#include "main.h"
#include "core.hpp"
#include <functional>
#include <map>
void wait(int ms){
pros::delay(ms);
}
Motor_Group::Motor_Group(std::initializer_list<pros::Motor> port_set)
{
this->motor_vector = std::vector(port_set);
}
pros::Motor Motor_Group::get(short idx)
{
returnthis->motor_vector[idx];
}
short Motor_Group::size()
{
returnthis->motor_vector.size();
}
void Motor_Group::move(short speed)
{
for(int i = 0;i<motor_vector.size();i++)
{
this->motor_vector[i].move(speed);//<- this move function is a function from the api in the 'main.h' , not the Motor_Group.move() one
pros::lcd::print(i+1,"moved");
}
this->speed = speed;
}
float Motor_Group::position()
{
float total = 0;
for(int i = 0;i<size();i++)
{
total += this->motor_vector[i].get_position();
}
return total / this->size();
}
void Motor_Group::tare()
{
for(int i = 0;i<this->size();i++)
{
this->motor_vector[i].tare_position();
}
}
/*...*/
The compiler does not actually compile files alphabetically.
You are probably using *.cpp on the command line, which provides an alphabetical list of cpp files and the compiler is compiling them in the given order.
But the order of compilation should not matter in general, so I'm not sure what's going on with your code.
It could be "undefined behavior".
It's probably the linking order that's changing things by creating a somewhat different memory layout in the two cases.
If that's true then there is an underlying error in your code, such as accessing a vector outside it's bounds.
Can you provide a link to a zip file of all the code?
Since you are creating global objects in h.cpp and initialize.cpp, the storage for these (except for the dynamic part of the vector storage) will go in a static data area. Apparently, the order in which those global objects are put into that area is affecting your program. That means that you are probably overflowing one of the objects and writing into the next one at some point. You need to look for an error of that type.\
Maybe add a check to your get routine to see if idx is ever out of range (below 0 or equal to or above the vector size).
I can, i will send it later. The thing now is that changing the name will solve it. In my main project with more files, this works but some files which included the h file still resulted in the same thing
A more elaborate technique: http://www.petebecker.com/js/js199905.html
Note that in the example at the end of Becker's article, the array of characters must be properly aligned:
What you describe should not happen, and those of us with many years or decades of experience recognize the problem in the sense that nonsensical "solutions" are actually a symptom of the problem(s) described to you.
This means that while it may seem that renaming solves the problem, we can assure you it hasn't. Minor alterations in the layout of the executable will undoubtedly bring the problem forward again in the future. It is merely hidden, not solved.
@dutch - you crack me up! That was just wonderful!
Had anyone has experience this? Is this normal to happen to global class objects? I have done the same thing using "extern" when using global variables. Why is this only happening with class objects? Is this normal?
"50% of the time" just means that you have a 50/50 chance of it working, depending on how the compiler orders the construction code. In your case, changing the order of the files listed on the compile line is what "flips the coin".
You need to ensure that the Motor objects are created before the Motor_Group objects that copy them, otherwise the Motor_Group objects will get uninitialized Motor objects, which is basically what you are seeing.
I think that putting all the globals in a single cpp file with the Motor objects before the Motor_Group objects would solve it, if that is feasible in your situation.
Another possibility is to store pointers/references to the Motor objects in the Motor_Groups instead of copying them.
EDIT: Here's a program that demonstrates the problem:
For me, compiling as g++ -std=c++11 -Wall -W -pedantic two.cpp one.cpp prints 42
but compiling as g++ -std=c++11 -Wall -W -pedantic one.cpp two.cpp prints 0.