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.
Related
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.
For example in foo.h:
typedef struct foo_t foo_t;
/* Lots of function declarations dealing with foo_t... */
int foo_print(const foo_t *foo); /* Print foo to stdout. */
int foo_fprint(FILE *f, const foo_t *foo); /* Print foo to file f. */
I don't want to litter foo.h with too many other header files that users of foo.h might not have wanted to include, but I do need to declare functions that take types such as FILE*. I doubt that I am the first to encounter this dilemma, so what do people usually do in these circumstances? Or am I misguided in wanting to avoid including stdio.h in my header files?
EDIT:
People seem not to be understanding my question. To clarify, here are some potential solutions:
Just include stdio.h and not worry about it causing conflicts in my clients' code (such as if they happened to have their own function that happened to be called getchar).
Use an #ifdef to find out if stdio.h had already been included, and only then declare the FILE*-related functions. The downside of this is that it would impose a particular ordering to #includes in my clients' code.
Move all I/O-related declarations to a separate header file such as foo_io.h.
What question is what is the best thing to do?
Short answer: you are trying to solve a non-existing problem.
If you use FILE, you include stdio.h or cstdio in C++. It's that simple.
Trying to "optimize" #includes, besides obvious cases of unused ones, will not buy you anything and cause problems.
You should strive to have header files compile cleanly in an empty source module. For example:
#include "myheader.h"
and that's it. If you put that in a C++ source file and compiled it with no other code, you should get no compiler errors.
If you do get errors, then you need to justify why there are errors. The only legitimate reason I would think of for errors is that the header is internal in your library, and was not meant to be used standalone by the user of your library.
If the header is supposed to be used by your clients, do not "fix" the problem by taking the test source file above and adding headers to the source. You fix it by including the proper headers within (in my simple case) myheader.h
Refering to the updated question:
Conditionally enabling or disabling blocks of code (or features) depending on order of included files stinks as hell. It's a straight way to hell.
If you want to enable or disable your functionality, making your code more modular, you can use preprocessor macros, possibly requiring user to explicitly choose compilation mode.
#ifdef USE_STDIO
#include <stdio.h>
#endif
lotsa lotsa code
#ifdef USE_STDIO
int foo_print(const foo_t *foo);
int foo_fprint(FILE *f, const foo_t *foo);
#endif
Downside of this solution: code becomes harder to follow.
Second option is to extract those methods to foo_io.h (and possibly foo_io.c). The downside of this solution is that you're forcing user to include two files instead of one.
You've already answered your own question. Both 1) and 3) are valid solutions. If you use FILE* in one of your functions then it only makes sense to use your function in combination with the header where FILE is declared. As others noted, there is no header that would forward declare FILE, so your only choice is to include stdio.h.
If your client includes your header file, assume that all the functions will be used. Do not use conditional compilation for cutting out include's. If I'd include your header file and see that that it contains a declaration of a function that uses FILE* I would expect to have stdio.h included as well.
If you're using a standard library functionality, just include that standard header full stop. Don't try to over-think that someone may have a function with the same name as something in the standard library: Their code is already fragile/broker and you shouldn't worry about such cases.
I can't make out if your code is C++ or C though (note that even though C++ may have roots in C they are distinct languages). If it's C++ you can use cstdio instead of stdio.h and use features from the std namespace instead of the global namespace. Otherwise if your code is C you have to use stdio.h
I have seen this countless of times. Instead of
#ifndef _common_h_
#define _common_h_
#endif /* _common_h_ */
people sometimes define their header files in following format:
#ifndef _common_h__479124197491641974591
#define _common_h__479124197491641974591
#endif /* _common_h__479124197491641974591 */
What is that random number good for? I just couldn't successfully google any answer to this.
The idea is to make it harder to trip your include guard unintentionally, and/or to avoid triggering someone elses' include guards.
For example, if you are writing a library, and you have a Common.h header, then using _common_h_ for the guard could prevent users of your library from having _common_h_ guards in their own libraries, which is not ideal. Adding a random number makes such collisions nearly impossible.
The problem
Include guards are often declared in the form:
#ifndef X
#define X
...
#endif
The programmer is free to choose, what we will call here as, a "name". This name is often unique within a single library, but it can happen (even if rare) that two libraries define the same name. This can potentially lead to terrible headaches.
The random numbers
Since the name is often not important outside of the specific file, we can choose (or other tools can do it for us) to include a random number within the name, which will make it much harder to cause name clashes.
#pragma once
You can avoid the problem in another way, by using:
#pragma once
This is a well supported extension, which is compatible with clang, gcc and mvc, as well as many other compilers.
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
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.