Help with header files in Pros

I am new to PROS for V5, and I’m used to RobotC. I’m confused about the purpose of header files, and I have a couple of questions.

In a code example I saw, tasks were defined in source, with corresponding header files in include that contained all of the declarations. I don’t usually use tasks, though, I just use functions and classes. Since I didn’t understand why both source and header files were necessary, I tried putting all of my classes and functions into header files in include, with nothing in source. To my surprise, this worked perfectly, and I was able to create classes and call the functions from opcontrol(). Is putting your code in header files a bad practice, and could this lead to problems?

Also, I am kind of confused about the purpose of #ifndef, #define, and #endif. I noticed these in the header files main.h and api.h, and in the code example that I saw the team had used these in the header files that they made. When I looked it up, it seemed like the reason had to do with not defining something twice, but I didn’t use this in my header files and it worked fine. I was curious, so I commented out this code from main.h and still the program worked fine. So what is the purpose of #ifndef, #define, and #endif, and should I put these into my header files?

Thanks for any help!

Check out this article about using header files:

https://docs.microsoft.com/en-us/cpp/cpp/header-files-cpp?view=vs-2017

And this thread about best practices:

2 Likes

It should be fine to put #ifndef #define and #endif in header files. Endif and Ifndef are used essentially as automated comments. So, If you set your Ifndef to a true variable or value, that code block (ending with endif) will be run. If false, that code will be ignored by the compiler.

Ok, I think I understand. So the first time the compiler runs includes main.h, it runs the code and sets a flag, and if it includes main.h again, the flag ensures that it doesn’t run the same code again. So am I correct in assuming that not using #ifndef is perfectly fine, it just might waste time by compiling the same code again?

See the first link I posted, under the section “Header Guards.”

Conditional preprocessor directives can be used in a couple different ways, but the most common include “header guards” which prevent multiple inclusion (see above), and conditional compilation, which allows you to, well, conditionally compile sections of code. Consider:

void autonomous() {
#ifdef RED_AUTON
    run_red_auton_routine();
#else
    run_blue_auton_routine();
#endif
}

The difference between these and normal conditional statements is that they are executed at (or just before) the code is compiled, rather than when it’s running. In this trivial example, you would be able to compile two versions of the same code for different situations (and maybe upload each to its own slot on the V5 or something)

1 Like

I understand now! Thanks for the help!