How should header file look like for C++ projects? - c++

I`ve studied C, and now I decided to switch to C++.
So, in C, I used #ifndef #endif in my header files. Should I use the same commands in C++? Or are there some alternatives?

Yes, the preprocessor works (mostly) the same way, so you should still use preprocessor directives to guard against including the same code more than once.
Any differences in functionality between the preprocessor in C and C++ are likely to be edge cases that are unlikely to be relevant at your current learning level.

The file/header relationship is identical in C and C++.
foo.h:
#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE
// your declarations (and certain types of definitions) here
#endif
The C++ preprocessor is essential the same when compared to it’s C counterpart. All directives will work in either language whether written in a header (.h) or a source file (.c, .cc, .cpp).
Read more about the wonders of headers here!

The answer from Commader_Quazar is right and enough.
ALternatively you can substitute:
#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE
// your declarations (and certain types of definitions) here
#endif
with:
#pragma once
// your declarations (and certain types of definitions) here
which lets you write 1 line of code instead of 3, and is less error prone (since in this case you don't have to worry about remembering to put #endif at the end of the file) however I personally prefer the first option.

Related

How can I include a C header that uses a C++ keyword as an identifier in C++?

I've been using C++ and compiling with clang++. I would like to include the <xcb/xkb.h> header for an X11 program I am writing.
Unfortunately this header uses explicit for some field names (such as line 727) and that is a keyword in C++.
Is there anyway to deal with this?
xcb/xkb.h:
// ...
#ifdef __cplusplus
extern "C" {
#endif
// ...
typedef struct xcb_xkb_set_explicit_t {
xcb_keycode_t keycode;
uint8_t explicit;
} xcb_xkb_set_explicit_t;
// ...
#ifdef __cplusplus
}
#endif
// ...
Use a macro to rename the fields:
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif
#define explicit explicit_
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#include <xcb/xkb.h>
#undef explicit
Using a keyword as a macro name is ill-formed in standard C++, but GCC, Clang (with pragma), and MSVC do accept it. (The standard says you "shall not" do it, cppreference clarifies that it means "ill-formed".)
How can I include a C header that uses a C++ keyword as an identifier in C++?
There is no standard-conforming solution to be able to include such header. In order to be able to include a header in C++, it must be written in valid C++. In case of a C header, it would thus have to be written in common subset of C and C++.
The ideal solution is to fix the header to be valid C++. A standard-conforming workaround is to write a C++ conforming wrapper in C.
(Not an answer to the exact question, but possibly useful for the general problem of interfacing C & C++)
How about using an intermediate set of C files (.c & .h) to wrap the incompatible header and provide a C++-compatible interface to the rest of your program? If that interface is high-level enough, then you would only need to include the incompatible header file in the wrapper .c file only, allowing the wrapper .h header file to be included in C++ code normally.
Depending on the details, you might end up doing some trivial copying of data, but the resulting C interface might be much more suited to your specific needs.
One solution is to add a generation step to your makefile that copies the header and renames the field, and include said autogenerated header instead.
(This is between difficult to impossible to do in the general case, but in this case given that the header isn't likely using explicit for anything else even just a simple (gnu) sed (s/\bexplicit\b/explicit_field/g or somesuch) would work. The trickier bit is figuring out the correct file to copy.)
Make sure that the location of the copied header is before the original header in your include path, in case something else in your includes indirectly includes the header.
Just changing a field name shouldn't have any effects on e.g. ABI, at least for a nominally-C-compatible header. (There are cases in C++ where renaming a field does affect things.)

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

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.

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

How to make C++ program work across compilers

I wanted to know how I would make my C++ program work across compilers. I wanted to make the program so if it's being compiled with borland it will use the clrscr() function otherwise it'd use system("CLS"). I've seen code that has done something similar but I couldn't find an explanation of what it does or how it works. Any help would be appreciated.
In general, to make a C or C++ program work across multiple compilers you want to confine yourself to standard C or C++ as much as possible. Sometimes you have to use compiler/platform specific functionality, though, and one way to handle that is via the preprocessor.
The predef project on SourceForge lists a bunch a preprocessor symbols that are defined automatically by various compilers, for various platforms, et cetera. You can use that information to implement what you need, for example:
void clearScreen() {
// __BORLANDC__ is defined by the Borland C++ compiler.
#ifdef __BORLANDC__
clrscr();
#else
system("cls");
#endif
}
One easy answer from the top of the head is define your own function calls and then translate it into real calls depending on the compiling parameters (with #ifdef preprocessing definitions - look which values are corresponding to which compiler).
example:
#if defined(__COMPILER_ONE__)
#define ClearScreen() clrscr()
#elif defined(__COMPILER_TWO__)
#define ClearScreen() system("CLS")
#else
#error "I do not know what to do!"
#endif
You would have to create a dedicated header file for this and to include it everywhere, of course.
(Of course you have to substitute COMPILER_ONE and COMPILER_TWO with relevant definitions :) )
How to make something work across different compilers is simple question which is very complex to answer! Your specific query about clearing the screen;
I would attempt it like this, first you have your own function say
void clear_screen();
And define it like this:
void clear_screen()
{
#ifdef LINUX
...
#eleif MS_WIN
...
#endif
}
Please note I have just guessed what the #define 's are. This is know as conditional complication, generally regarded as evil, but containing it in a function reduces the harm a little.
The way it's typically done is through the magic of the preprocessor or makefiles. Either way, you hide the implementation details behind a common interface in a header file, such as void clearscreen(). Then in a single source file you can hide the Borland implementation behind #ifdef BORLAND, and similarly for other implementations. Alternatively, you can put each implementation in a separate source file, and only compile the proper one based on a variable in a makefile.
You can do this by checking compiler macros with the #ifdef compiler macro:
#ifdef BORLAND
borland();
#else
otherCompiler();
#endif