How to use a header file without a cpp file - c++

I am a java developer, but I have had to learn C++ recently and I am confused about some things. What I would like to do is create a 'global' header file, which has a list of #define variables which will be constant throughout the suite I am creating. I created the header file, and I added some variables
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define SM_START 1001;
#define SM_PAUSE 1002;
#define SM_STOP 1003;
#define SM_SAVE 1004;
#define SM_DISCARD 1005;
#define SM_SETUP 1007;
#endif // CONSTANTS_H
My problem is that I can't access these...
I have included the header file where I need it, but there is no way for me to access the constants inside of it. Do I Have to have a .cpp file? is there a way for me to access the constant variables?

First: You shouldn't put the semicolons at the end of the #define. #define is a preprocessor directive, meaning that it basically does text replacement of the defined name with the content. So if you do something like int a = SM_STOP + 1; it would be preprocessed to int a = 1003; + 1; with your code, which is not what you want.
Second: Headers are generally not compiled themselves but only for inclusion into *.cpp files or other headers (where #include is once again a text substitution). Therefore, yes you need to have a .cpp file somewhere (well not exactly, first of all you can choose a different extension and second you could even give the compiler a header as compile unit, but I would advise against it, at least until you know what you are doing). However you do not need to have a .cpp file for your constants, just #include your header into whatever file you want to use the constants in.
Third: Why are you using preprocessor defines here? This seems to be like a perfect job for an enum. Then you could put it into a namespace/struct for removing the need to prefix them (with SM_). Or you could just use C++11's new enum class, which behaves much like java's enums. I would avoid preprocessors wherever possible. Since it is simply text replacement and it doesn't respect any scoping and such, which makes it easy to get into problems (like with your semicolons).

The problem is that yuu have semicolons after #define. This is the only thing preventing you from using your "constants", which are not technically constants; they are preprocessor definitions.
Logically, the C++ compiler runs the text of your program through a preprocessor, a text filter that executes the directives starting in #. The #define directive instructs preprocessor to find all occurrences of its left part, and replace them verbatim with its right part. In your case, it includes semicolons, resulting in invalid expressions after replacement.
For example,
if (command == SM_DISCARD) ...
becomes
if (command == 1005;) ...
This is an error, and the compiler reports it as invalid syntax.

Use #include <constants.h> or whatever your filename is to include this file. Also, you don't need the semi-colons. #defines are text replacements done on the code by the compiler.

You don't need a cpp file. Including the header is enough.
The preprocessor expands your defines with whatever is after it.
SM_START will become 1001;
So an expression like:
int x = SM_START;
will translate to
int x = 1001;;
which is still legal.
But that semicolon could lead to trouble in something like:
int x = SM_START * 10;
which will be expanded to:
int x = 1001; * 10;
which is obviously illegal.
Also, preprocessor directives are not to be confused with globals. Even though you probably shouldn't be using globals, using #defines is probably worse than defining a class Global or just using variables grouped in a namespace.

Related

Can I define a macro in a header file?

I have a macro definition in MyClass.h, stated as such:
#define _BufferSize_ 64
I placed the include directive for MyClass.h inside of main.cpp:
#include "MyClass.h"
Does this mean I can use _BufferSize_ in both main.cpp and MyClass.h? Also, is this good practice?
Yes, it would work. (Disregarding the problem with underscores that others have pointed out.)
Directive #include "MyClass.h" just copies the whole content of file MyClass.h and pastes it in the place of the #include. From the point of view of the compiler there is only one source file composed of the file specified by the user and all included files.
Having said that, it would be much better if you use in-language construction instead of preprocessor directive.
For example replace:
#define _BufferSize_ 64
with
constexpr size_t BufferSize = 64;
The only thing it does differently than the #define is that it specifies the type of the value (size_t in this case). Beside that, the second code will behave the same way and it avoids disadvantages of preprocessor.
In general, try to avoid using preprocessor directives. This is an old mechanism that was used when c++ coudn't do that things in-language yet.
Yes, that is the purpose of header files: creating declarations and constants in one file that you can "include" into translation units whenever you like.
However, your macro name is illegal, and a nice constexpr size_t BufferSize = 64 would be more idiomatic nowadays; even before recent versions of C++, a typed constant would be preferable to a macro in many cases.
First, regarding the identifier _BufferSize_, the standard states that:
3. ...some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required.
(3.1) Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
So having such an identifier in your code would lead to undefined behavior.
And as already suggested in the comments, using macro variables is not good practice in C++. You can use a const int instead.
Replying 3 years later because the answers are wrong and this is first google search result in certain keywords.
https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros
Avoid defining macros, especially in headers; prefer inline functions, enums, and const variables. Name macros with a project-specific prefix. Do not use macros to define pieces of a C++ API.
Highlight by me, not in original text.

Definition and declaration of global variables using preprocessor trick

I am currently looking through the code written by senior engineer. The code works fine but i am trying to figure out one detail.
He uses quite a few global variables and his code is broken down into a lot of separate files. So he uses a technique to make sure that global vars are declared everywhere where he needs to access them but are only defined once.
The technique is new to me but I read few articles on the internet and got some understanding about how it works. He uses
#undef EXTERN
followed by conditional definition of EXTERN as an empty string or actual extern. There is a very good article here explaining how it works. Also there is a discussion here
What gets me confused is that all examples I saw on the web suggest to include header file in a regular way in all of the source files that need it except for one. In this single special case line that includes header is preceded by definition of a symbol that will ensure that EXTERN will be defined to an empty string and .. so on (see link above). Typically this single special case is in main or in a separate source file dedicated to the declaration of global variables.
However in the code that I am looking at this special case is always in the source file that corresponds the header. Here is the minimal example:
"peripheral1.h" :
#undef EXTERN
#ifndef PERIPHERAL_1_CPP
#define EXTERN extern
#else
#define EXTERN
#endif
EXTERN void function1(void);
"peripheral1.cpp" :
#define PERIPHERAL_1_CPP
#include "peripheral1.h"
function1()
{
//function code code here
}
Everywhere else in the code he just does
#include "peripheral1.h"
My question is how and why does that work? In other words, how does compiler know where to define and where to just declare function (or variable, or class ...)? And why is it ok in above example to have the lines :
#define PERIPHERAL_1_CPP
#include "peripheral1.h"
in actual peripheral1.cpp rather then in main.cpp or elsewhere?
Or am I missing something obvious here?
All the source files, except "perripheral1.cpp", after preprocessing contain a sequence
of external variable declarations like:
extern int a;
extern int b;
extern int c;
In peripheral1.cpp only, after preprocessing, there will be a sequence of declarations:
int a;
int b;
int c;
int d;
which are tentative definitions of the corresponding variables, which, under normal circumstances are equivalent of the external definitions :
int a = 0;
int b = 0;
int c = 0;
int d = 0;
End result is, variable are declared everywhere, but defined only once.
PS. To be perfectly clear ...
In other words, how does compiler know where to define and where to
just declare function (or variable, or class ...)?
The compiler knows where to declare, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a declaration.
The compiler knows where to define, whenever it encounters a grammatical construct, which is defined in the standard to have the semantics of a definition.
In other other words, the compiler does not know - you tell it explicitly what you want it to do.
Nostalgia
Ahh, this takes me back a fair way (about 20 years or so).
This is a way for C code to define global variables across multiple files: you define the variable once using a macro to ensure it is defined exactly only once, and then extern it in other C code files so you can utilise it. Nowadays it is quite superfluous in many instances, however it still has its place in legacy code, and will (most likely) still work in many modern compilers, nut it is C code not C++.
Normally the likes of #define PERIPHERAL_1_CPP is utilised to ensure uniquenesss of inclusion like a #pragma once
In my own code I would use something like:
#ifndef PERIPHERAL_1_CPP
#define PERIPHERAL_1_CPP
// my includes here
// my code here
#endif
That way you can #include the file as many times as you want all over your code, in every code file even, and you will avoid multiple definition errors. To be fair I normally do it with the .h files and have something like:
// for absolutely insane safety/paranoia
#pragma once
// normally sufficient
#ifndef PERIPHERAL_1_H
#define PERIPHERAL_1_H
// my includes here
// my code here
#endif
I have never tried it on cpp files but wil llater tonight to see if there is any benefit one way or the other:)
Give me a shout if you need any more info:)

how to #define macro only to specific files?

I have a special macro defined in macro.h, but I want it to be valid only in part of my source files (h/cpp),
how can I do that?
I am afraid that some "bad" user included the macro.h before the source files that must not be familiar with the macro.
how can I prevent it?
It is possible to have macros that are defined only in a files scope by using #undef. E.g. :
#define MACRO 1
int a = MACRO;
#undef MACRO
int b = MACRO; // ERROR
However, this does not work across files unless you rely on the order of includes, which would be bad.
If you want to use macros defined in a macro.h in sources, you could have a second unmacro.h and include that at the end of the source:
// foo.cpp
// other includes
#include "macro.h"
// no other includes!
// contents of the source
#include "unmacro.h"
However, I would not recommended it because it is error-prone. Better reconsider if you need to use macros at all. In modern C++ their valid uses are extremely rare.
You can't. If it's in macro.h, and that file is public, there's no going around it.
A common technique is defining the macro conditionally:
#ifdef SOME_CONDITION
#define MY_MACRO
#endif
but a "bad" user can just as well define SOME_CONDITION.
What you should do is separate public headers from private ones. As you stated the problem, the macro you want hidden probably shouldn't be in a public header at all.
You cannot control the area of effect of the macro, especially if you have it in a .h which is included everywhere.
If you want it to exist only in a few .h and .cpp files then one option is to (re)define it at the top of those cpp files. You could also seperate just these macros into its own .h and include it only in the cpp files that need it and not expose it to users of your code.
You might want to give a more specific example if you want more specific answers

Structs inside #define in 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.

What is the purpose of the #define directive in C++?

What is the role of the #define directive?
#define is used to create macros in C and in C++. You can read more about it in the C preprocessor documentation. The quick answer is that it does a few things:
Simple Macros - basically just text replacement. Compile time constants are a good example:
#define SOME_CONSTANT 12
simply replaces the text SOME_CONSTANT with 12 wherever it appears in your code. This sort of macro is often used to provide conditional compilation of code blocks. For example, there might be a header included by each source file in a project with a list of options for the project:
#define OPTION_1
#define OPTION_2
#undef OPTION_3
And then code blocks in the project would be wrapped with matching #ifdef/#endif# blocks to enable and disable those options in the finished project. Using the -D gcc flag would provide similar behaviour. There are strong opinions as to whether or not this method is really a good way to provide configuration for an application, however.
Macros with arguments - allows you to make 'function-like' macros that can take arguments and manipulate them. For example:
#define SQUARE(x) ((x) * (x))
would return the square of the argument as its result; be careful about potential order-of-operations or side-effect problems! The following example:
int x = SQUARE(3); // becomes int x = ((3) * (3));
will works fine, but something like:
int y = SQUARE(f()); // becomes int y = ((f()) * (f()));
will call f() twice, or even worse:
int z = SQUARE(x++); // becomes int z = ((x++) * (x++));
results in undefined behaviour!
With some tools, macros with arguments can also be variadic, which can come in handy.
As mentioned below in the comments, overuse of macros, or the development of overly complicated or confusing macros is considered bad style by many - as always, put the readability, maintainability, and debuggability of your code above 'clever' technical tricks.
#define (and it's opposite, #undef) can be used to set compiler directives which can then be tested against using #ifndef or #ifdef. This allows for custom behaviors to be defined within the source file. It's used commonly to compile for different environments or debug code.
An example:
#define DEBUG
#ifdef DEBUG
//perform debug code
#endif
The most common use (by far) of #define is for include guards:
// header.hh
#ifndef HEADER_HH_
#define HEADER_HH_
namespace pony {
// ...
}
#endif
Another common use of #define is in creating a configuration file, commonly a config.h file, where we #define macros based on various states and conditions. Then, in our code we test these macros with #ifdef, #elif defined() etc. to support different compiles for different situations. This is not as solid as the include-guard idiom and you need to be careful here because if the branching is wrong then you can get very obscure compiler errors, or worse, runtime behavior.
In general, other than for include guards you need to think through (twice, preferably) about the problem, and see if you can use the compiler rather than the preprocessor to solve it. The compiler is just smarter than the preprocessor. Not only that, but the compiler can't possibly confuse the preprocessor, whereas the preprocessor most definitely can confuse and mislead the compiler.
The #define directive has two common uses.
The first one, is control how the compiler will act. To do this, we also need #undef, #ifdef and #ifndef. (and #endif too...)
You can make "compiler logic" this way. A common use is to activate or not a debug portion of the code, like that:
#ifdef DEBUG
//debug code here
#endif
And you would be able to for example compile the debug code, by writing a #define DEBUG
Another use of this logic stuff, is to avoid double includes...
Example, file A, #includes file B and C. But file B also includes C. This likely will result in a compilation error, because "C" exists twice.
The solution is write:
#ifndef C_FILE_INCLUDED
#define C_FILE_INCLUDED
//the contents of header "c" go here.
#endif
The other use of #define, is make macros.
The most simple ones, consist of simple substitutions, like:
#define PI 3.14159265
float perimeter(float radius) {
return radius*2*PI;
}
or
#define SHOW_ERROR_MESSAGE printf("An serious error happened");
if ( 1 != 1 ) { SHOW_ERROR_MESSAGE }
Then you can also make macros that accept arguments, printf itself usually is a macro, created with a #define in a header file.
But this should not be done, for two reaons:
first, the speed os macros, is the same of using inline, and second, we have c++ templates, that allow more control over functions with variable type. So, the only reason to use macros with arguments, is make strange constructs, that will be hard to understand later, like metaprogrammed stuff...
In C++, #define has very narrow, specialized roles:
Header guards, described in other answers
Interacting with the standard libraries. For instance, #defining WINDOWS_LEAN_AND_MEAN before including windows.h turns off certain often-problematic macros like MAX.
Advanced macros involving stringization (ie, macros that print debugging messages) or token-pasting.
You should avoid using #define for the following purposes. The reasons are many; see for instace this FAQ entry.
Compile-time constants. Use const instead.
Simple macro functions. Use inline functions and templates instead.
in C or C++ #define allows you to create preprocessor Macros.
In the normal C or C++ build process the first thing that happens is that the PreProcessor runs, the preprocessor looks though the source files for preprocessor directives like #define or #include and then performs simple operations with them.
in the case of a #define directive the preprocessor does simple text based substitution.
For example if you had the code
#define PI 3.14159f
float circum = diameter*PI;
the preprocessor would turn it into:
float circum = diameter* 3.14159;
by simply replacing the instances of PI with the corresponding text. This is only the simplest form of a #define statement for more advanced uses check out this article from MSDN
inCorrectUseOfHashDefine()
{
The role of #define is to baffle people who inherit your code with out of the blue statements like:
foreverandever
because of:
#define foreverandever for(;;)
}
Please favour constants over #define.
It also for setting compiler directives...
Most things about #defines have been already told, but it's not clear that C++ has better replacements for most of their uses:
#define to define numerical constants can be easily replaced by a const "variable", that, as a #define, doesn't really exist in the compiled executable. AFAIK it can be used in almost all the situations where you could use a #defined numerical constant, including array bounds. The main advantage for me is that such constants are clearly typed, so there's no need to add casts in the macros "just to be sure", and are scoped, so they can be kept in namespaces/classes/functions, without polluting all the application.
const int max_array_size=50;
int an_array[max_array_size];
#define to create macros: macros can often be replaced by templates; for example, the dreaded MAX macro
#define MAX(a,b) ((a)<(b)?(b):(a))
, which has several downsides (e.g. repeated arguments evaluation, inevitable inline expansion), can be replaced by the max function
template<typename T> T & max(T & a, T & b)
{
return a<b?b:a;
}
which can be type-safe (in this version the two arguments are forced to be of the same type), can be expanded inline as well as not (it's compiler decision), evaluates the arguments just once (when it's called), and is scoped. A more detailed explanation can be found here.
Still, macros must still be used for include guards, to create some kind of strange language extensions that expand to more line of code, that have unbalanced parenthesis, etc.