Structs inside #define in C++ - c++

Being pretty new to C++, I don't quite understand some instructions I encounter such as:
#ifndef BOT_H_
#define BOT_H_
#include "State.h"
/*
This struct represents your bot in the game of Ants
*/
struct Bot
{
State state;
Bot();
void playGame(); //plays a single game of Ants
void makeMoves(); //makes moves for a single turn
void endTurn(); //indicates to the engine that it has made its moves
};
#endif //BOT_H_
What I don't understand is the "#ifndef BOT_H_" and the "#define -- #endif"
From what I gather, it defines a constant BOT_H_ if it's not already defined when the precompiler looks at it. I don't actually get how the struct inside it is a constant and how it is going to let me access the functions inside it.
I also don't see why we're doing it this way? I used C++ a while back and I wasn't using .h files, so it might be something easy I'm missing.

This is known as an include guard, to prevent the contents of a header file from being #included more than once.
That is, it prevents the contents of the header file from being copied into the file that #includes it when it has already #included it before.
The #define isn't defining a constant for the struct, but it's simply defining a constant with no value. If that constant was previously defined, the struct will not be redeclared.

It's called "include guard". It protects you from redefinitions occuring when a header is included more than once. There's also non-standard #pragma once that does the same thing, but might not be supported everywhere.

It does not define a constant whose value is the struct. It defines a constant with an empty value.
It's there so that the content of the header is not included twice. Basically it says something like:
if (!bot_h_included)
{
bot_h_included = true;
// code from the header
}

this is called a header guard it stops the compiler compiling or including the code more than once it is similar to pragma once

Just a side note, I don't recommend using #pragma once I see it a lot in a MVC compatible compilers but just a couple of weeks ago I was working with HP UX and the HP-CC does not support #pragma once, I strongly recommend using #ifndef/#define combinations.

Related

Why do you need inclusion guard for C++ header files?

I get roughly what it does. What I don't understand is why it's not the default? What are the use cases where some header file would need to be included multiple times?
The reason it's not the default is primarily historical these days -- when the C language was formalized, #include was specified that it must act exactly as if the user had copy-and-pasted the specified file's contents at the location of the #include-line; and C++ wanted (and wants) to remain as compatible as possible with C, so C++ inherited that behavior from C.
As for a use-case where including the same header file more than once might be useful; one instance where I found it useful was for simulating a templated-container-class in C (because C doesn't support templates directly). I had a container-implementation-header-file that looked something like this (but more elaborate; I'm showing a simplified version here for readability):
// MyContainerImplemention.h
// be sure to #define MYTYPE and MYARRAYSIZE
// before #include-ing this file!
struct ArrayOf##MYTYPE
{
MYTYPE arrayOfItems[MYARRAYSIZE];
};
inline void Set##MYTYPE##Item(struct ArrayOf##MyType * container, int which, MYTYPE item)
{
container[which] = item;
}
[... and so on for various other MYTYPE-specific methods ...]
... then my .c files could do something like:
#define MYTYPE int
#define MYARRAYSIZE 10
#include "MyContainerImplementation.h"
#undef MYARRAYSIZE
#undef MYTYPE
#define MYTYPE short
#define MYARRAYSIZE 15
#include "MyContainerImplementation.h"
#undef MYARRAYSIZE
#undef MYTYPE
struct ArrayOfint myInts;
struct ArrayOfshort myShorts;
SetintItem(&myInts, 5, 12);
SetshortItem(&myShorts, 3, 2);
[...]
... and end up with the container "class" and its associated methods implemented for each data-type, without having to manually write a new implementation of the container "class" each time.
Yes, it was extremely ugly -- but not as ugly as having to manually write out thousands of lines of redundant container-code would have been. (The real container-implementation-header-file implemented a hash table and was several hundred lines long)
Without include guards or #pragma once the compiler would have to maintain a list of included files. This is not easy, because of different possible paths to these files (and #pragma once doesn't completely solve this) and would be expecting a bit much of the original C compilers, which had to work with very limited memory.
What's true today is not necessarily true when C came about and the C pre-processor, upon which the C++ one is based, was created.
#pragma once is just a step towards having proper C++ modules so this annoying historical legacy is finally eliminated.
Yes, it's valid to include a file multiple times, and yes, each time it's included it can behave in entirely different ways. This is why making pre-compiled headers is a huge headache for compiler developers.
Guard blocks or #pragma once are included in order to prevent a file from being included multiple times.
#pragma once, while supported on most compilers, is not an official part of the c++ standard, and may not work on every compiler. You can use a guard block, which will work on any compiler. An example of a guard block in the file MyClass.hpp would be:
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
//Code here
#endif

Merits of defining constants in header or implementation files

Throughout a C++ codebase I'm working in, the pattern for declaring constants looks something like this.
// module_constants.h
#ifndef MODULE_CONSTANTS
#define MODULE_CONSTANTS
namespace module {
extern const int SOME_CONST;
}
#endif
// module_constants.cpp
#include "module_constants.h"
namespace module {
const int SOME_CONST = 1;
}
What are the merits of this approach rather than defining all of the constant values in the header?
The single advantage I know of is that you only have to recompile a single cpp-file when you change the constant’s value and not every file that directly or indirectly includes the header file.
That can be particularly useful when you provide a dynamically linked library and want to patch it without recompiling the actual application.
Some drawbacks are that
(as latedeveloper wrote) you can't use them at places where a constant expression is required (e.g. array bounds or template parameters) outside of the cppfile, in which you defined it.
you make the optimizer's life harder.
from a tooling perspective e.g. intellisense won't show you it's value.
Well, by putting it in the header you'd run into the one-definition rule if you include it in more than one cpp file.
But, on the other hand, you can create it as a constexpr in the header I believe.

Need clarification on #ifndef #define

The code I am working has multiple headers and source files for different classes face.cc, face.hh, cell.cc, cell.hh edge.cc edge.hh and the headers contain includes like this,
#ifndef cellINCLUDED
#define cellINCLUDED
#ifndef faceINCLUDED
#define faceINCLUDED
I saw through http://www.cplusplus.com/forum/articles/10627/ and saw the way to write include guard is
#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__
So in above code that I am working on, does compiler automatically understands it is looking for face.hh or cell.hh files?
better question : Is writing __CELL_H_INCLUDED__ same as cellINCLUDED ?
#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__
So in above code that I am working on, does compiler automatically
understands it is looking for face.hh or cell.hh files?
No, the compiler doesn't automatically understand what you mean.
What really happens is that, when compiling a translation unit, the Compiler holds a list of globally defined MACROs. And so, what you are doing is defining the MACRO __MYCLASS_H_INCLUDED__ if it doesn't already exists.
If that macro is defined, that #ifndef until #endif will not be parsed by the actual compiler.
Hence you can test for the existence of that MACRO to determine if the Compiler has parsed that header file to include it once and only once in the translation unit... This is because the compiler compiles each translation unit as one flattened file (after merging all the #includes)
See https://en.wikipedia.org/wiki/Include_guard
Is writing __CELL_H_INCLUDED__ same as cellINCLUDED ?
Yes it is.... The reason some prefer using underscored prefixed and suffixed MACROs for include guards is because they have extremely low probability of ever being used as identifiers... but again, underscore could clash with the compiler...
I prefer something like this: CELL_H_INCLUDED
If you use cellINCLUDED, there are chances that someday, somebody may use it as an identifier in that translation unit
The preprocessor definitions have no special meaning. The only requirement is that they stay unique across the modules, and that's why the file name is typically a part of them.
In particular, the mechanics for preventing double inclusion aren't "baked in" the language and simply use the mechanics of the preprocessor.
That being said, every compiler worth attention nowadays supports #pragma once, and you could probably settle on that.
As the link you have referenced says, "compilers do not have brains of their own" - so to answer your question, no, the compile does not understand which particular files are involved. It would not even understand that '__cellINCLUDED' has anything conceptually to do with a specific file.
Instead, the include guard simply prevents the logic contained between its opening #ifndef and closing #endif from being included multiple times. You, as the programmer, are telling the compiler not to include that code multiple times - the compiler is not doing anything 'intelligent' on its own.
Nope, This is essentially telling the compiler/parser that if this has already been put into the program, don't puthave already been loaded.
This should be at the top (and have an #endif at the bottom) of your .h file.
Lets say you have mainProgram.cpp and Tools.cpp, with each of these files loading fileReader.h.
As the compiler compiles each cpp file it will attempt to load the fileReader.h. unless you tell it not to it will load all of the fileReader file in twice.
ifndef = if not defined
so when you use these (and the #endif AFTER all your code in the .h file)
you are saying:
if not defined: cellINCLUDED
then define: cellINCLUDED with the following code:
[code]
end of code
so this way when it goes to load the code in your .h file a second time it hits the if not defined bit and ignores the code on the second time.
This reduces compile time and also means if you are using a poor/old compiler it isn't trying to shove the code in again.

C++ Header #define compiler error

I'm learning C++ and I'm at a fairly low level still. - I'm currently looking at using header files and I have a two part question.
Part 1
As I understand them so far, header file definitions are similar to hard coded strings within VB.net? For example I can do the following #define STOCK_QUANTITY 300 and then reference my definition when using it within functions? I assume this works the same way as VB.net strings as I only need to change the value in one place should I need to make changes to the definition and my program references the number 300 on a few hundred different lines?
Part 2
Now, as I said I'm still learning so I'm still doing ye old multiplication tasks. I'm good within using functions with my main .cpp file but I'm not moving on to header files. This is my code snippet thus far.
add.h
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
#endif
main.cpp
#include "stdafx.h"
#include <iostream>
#include "add.h"
int main()
{
using namespace std;
cout << add(3, 4) << endl;
return 0;
}
When trying to run this I receive 2 build errors and it will not compile.
Apologies is these are silly questions, but I would appreciate insight, tips or even some other things I should consider. Thanks.
EDIT
Based on an answer I've changed my add.h too
#ifndef ADD_H
#define ADD_H
int add(int x, int y)
{
return x + y;
}
#endif
As soon as I read the answer I realised I hadn't even told the function what to do :( - Gosh.
You have not added a function body for the function add
int add(int x, int y)
{
// add stuff here
}
This can be done in either the header file, or a seperate cpp file for add. You are trying to call the function that has no code. This is known as a function prototype.
You have only declared that the function add exists, which is why you can call it. But you don't actually define the function anywhere.
In C++ you have to differ between declaration and definition. Sometimes those are done at the same time, like when declaring a local variable. Other times you separate them, like when having a function prototype in a header file (like you do) then that's the declaration. The definition of the function is then the implementation of the function.
After the edit, you now have another problem. And that is if you include the header file in multiple source files, each of those source files (formally known as translation units) will have the function defined and you will get an error because of that.
It can be solved by making the function static or inline. Or better yet, create a new source file (like add.cpp) where you have the definition of the add function, and keep only the declaration (prototype) in the header file.
As for part 1 of your question:
While #defines do as you described, there are some of disadvantages with using them (e.g. They are parsed by the pre-processor, and not by the compiler so no type checking, and also you can get funky errors if you have slightly more complicated macros.
So while your statement is valid, in that it defines a global constant that you only need to modify in one place, and can use in multiple places, for that purpose it is better to have an actual constant variable in the header file:
e.g.
const int STOCK_QUANTITY = 300;
Now you explicitly name it an integer, and also the compiler can perform extra checking.
See also Item 3 in Effective C++ by Scott Meyer (which is a must read in my opinion if you are serious about contineouing programming in c++, although you need allready some experience before reading that.)

File Local Define

This question more falls into the category of best practices, and clean/safe code for distribution.
I'm working on a math library in C++, for my portfolio, and to use during my last two semesters of College. I want this library to be very easy to use, and to minimize the possibilities of conflicts with pre existing code.
For readability I'm defining TEMP_T as a template for a class, at the top of each of my header files (math/matrix/vec/quaternion). It looks like the following:
#ifdef TEMP_T
#define UNDEF_TEMP_T TEMP_T // Used to reset any other definitions later.
#endif // TEMP_T
#define TEMP_T template<class T> // Used to make the code more readable.
Later on, at the end of the file, I reset the pre existing definition, if nessicary with the following:
#undef TEMP_T // Get rid of our definition.
#ifdef UNDEF_TEMP_T
#define TEMP_T UNDEF_TEMP_T // Reset the previous definition, if it existed.
#undef UNDEF_TEMP_T
#endif // UNDEF_TEMP_T
My question: Would this successfully create a define visible to the file, and the file alone? If so, is this how you would go about accomplishing such a thing? If not, would you be so kind as to give me some insight on your rational behind your ways of doing things?
IMO that is much less readable, falls into the class of pre-processor abuse and I would seriously recommend using the actual definition which will make your code more readable by others which is the point of readability.
In my eyes, you reduce readability this way. This would be the way to reduce the number of characters to be typed/read, but it increases the number of needed human-interpretations, too, which is a bad thing.
On top of that, if anyone has defined TEMP_T in their own code, they would loose their definition by including your headers.
// my code.cpp
#define TEMP_T( var, vartype ) myclass<vartype> var( ##var );
#include <yourmathlib.h>
TEMP_T( anint, int ) // breaks. hard to find the real error.
As a consequence you may define a library-specific MYMATHLIB_TEMP_T, which further decreases readability :)
You can just #include the header file where you declared the template from your other header files.
And if you want to make sure that you don't include the same file twice from 2 different files, you can have
#ifndef MYMATHLIB_TEMP_T
#define MYMATHLIB_TEMP_T
// ... template ...
#endif
around the template header file.
you could just define TEMP_T in an header file and use that header in all your code, maybe you can try to test if your header is included by some macro.
But this way of doing things increases the complexity to read your code.
Why not simply put your template class in a namespace? If you stick it in an namespace, you avoid all the nasty macro stuff. namespaces were explicitly designed to allow code units to be isolated form each other without naming conflicts.