#Header guards
1 messages · Page 1 of 1 (latest)
// some_header_file.hpp
#ifndef SOME_HEADER_FILE_HPP
#define SOME_HEADER_FILE_HPP
// contents of header
#endif //SOME_HEADER_FILE_HPP
it's basically wrapping the contents of the header file in macros similar to these ones
@weary sphinx has reached level 1. GG!
yes
but even without header guards you can
what header guards solve is when one .cpp file includes a header multiple times, either directly or indirectly
by indirectly I mean, you have file.cpp, a.h b.h and c.h
if file.cpp include a.h and b.h
and both a.h and b.h include c.h
then it's like file.cpp includes c.h twice
but header guards prevent the duplication of the code contained in c.h
No, in your example, header guards are unnecessary, because "get.h" is included only once in every compilation unit. Also, what is "square.h"?
The problem is if your program looks something like this:
get.h
#ifndef get
#define get
int getOne();
int getTwo(int sideLength);
struct Getter { int x, int y};
#endif
square.h
#include "get.h"
void processSquare(Getter g);
main.cpp
#include "get.h"
#include "square.h"
#include <iostream>
int main()
{
std::cout << "a one has " << getOne() << '\n';
std::cout << "a one * 2 is " << getTwo(2) << '\n';
return 0;
}
To understand it better, remember that the headers are just copy-pasted into the source code.
main.cpp after preprocessing with header guards:
// get.h
int getOne();
int getTwo(int sideLength);
struct Getter { int x, int y};
// square.h
// get.h is skipped because the header guard turns off all the definitions in that file
void processSquare(Getter g);
// iostream
[... iostream definitions ...]
int main()
{
std::cout << "a one has " << getOne() << '\n';
std::cout << "a one * 2 is " << getTwo(2) << '\n';
return 0;
}
main.cpp after preprocessing if you remove header guards:
// get.h
int getOne();
int getTwo(int sideLength);
struct Getter { int x, int y};
// square.h
// square.h includes full get.h header
int getOne();
int getTwo(int sideLength);
struct Getter { int x, int y};
void processSquare(Getter g);
// iostream
[... iostream definitions ...]
int main()
{
std::cout << "a one has " << getOne() << '\n';
std::cout << "a one * 2 is " << getTwo(2) << '\n';
return 0;
}
But yeah, header guards are an old solutoin, #pragma once is the way to go now.
don't use #pragma once since that isn't portable
generally, the convention is to take the file name, replace the dot with an underscore and convert it to uppercase for the macro you're defining
so get.h becomes GET_H
Have you ever used a compiler where it doesn't work?
For the vast majority of people it's perfectly fine
i do not care
lol
It's not true, it's actually very portable. There are at least 17 different compilers which support that.
It's more portable than some of the C++17 features 🙂