I want to include a header file only if a certain function body is called?
Is this possible or recommended in C++?
No.
You've got it a bit wrong; #include is not processed at run-time, at all. It's not possible to #include a file based on a program's execution characteristics; once the program executes its source is fixed (since it's already compiled).
Possible, yes; recommended no, not usually.
#include is process and an early stage of parsing so works in many places with no regard for the language context at the point of the include.
Note that the include will happen regardless of whether the function is called so it probably isn't going to solve the problem that you are trying to solve. The file included will be placed directly inside the function body so the include file would have to be designed to be included at such a point in the source file.
You're obviously biased by higher-level languages, such as Python, in which is possible to do things like:
if ( a ):
from whatever import whatever_I_need
else:
from whatever_else import whatever_I_need
However, in C++ this is evaluated at compile time (well, actually, #include is a preprocessor directive and it is even evaluated before compile time). Putting that inside a block of an if-else construction will only lead to compilation errors. Just take into account that #include is just a way to dump the contents of a file (normally a header (interface) file) into another one that needs its declarations. Very low level. It will be included anyway.
You can #include inside a function body, but this does not mean that the header file is only included when the function body is called.
The content of the header file will be included by the preprocessor at compile time, and thus the code will always be present in the function.
Obviously, the code is only executed when the function is called.
While you can put a #include inside a function body, it is not what you want to do. There is no way to include a header file only if a certain function is called because the include happens before compile time, but the function call happens at runtime.
Okay, the question was a little off the track, but the actual matter is important.
If for a portion of your methods you actually need to depend on a library that most users won't care about, it's perfectly reasonable to be willing to spare them this unneeded dependency.
You can do this by manipulating preprocessor tokens.
/// myClass.h
/// In order to use BigDep, you need to:
/// - define `MYPROJECT_BIGDEP_USE` before included this header
/// - have `<bigdep-install-path>/include` in your include path
/// - link with `libbigdep.so`
class MyClass
{
public:
void foo() const;
#ifdef MYPROJECT_BIGDEP_USE
void bigDep() const;
#endif // MYPROJECT_BIGDEP_USE
};
/// myClass.cpp
#include "blah.h"
#include "bar.h"
#ifdef MYPROJECT_BIGDEP_USE
#include <bigdep.h>
#endif // MYPROJECT_BIGDEP_USE
void MyClass::foo() const { /**/ }
#ifdef MYPROJECT_BIGDEP_USE
void MyClass::bigdep() { /**/ }
#endif // MYPROJECT_BIGDEP_USE
This way, you have to compile mode, depending on whether the symbol MYPROJECT_BIGDEP_USE is defined or not.
On gcc, you can define symbol on the command line using -D like in -DMYPROJECT_BIGDEP_USE. On Visual Studio it's with /D like in /DMYPROJECT_BIGDEP_USE.
Another option for you user is to wrap your header:
// myProjectMyClass.h
#define MYPROJECT_BIGDEP_USE
#include <myClass.h>
And only ever include "myProjectMyClass.h" and never your header directly.
The use of these preprocessor directives is quite common. For example, when installing the cx_Oracle python module, the installer checked for the version of oracle I used from my environment variables and disabled a number of methods that were not available for it directly at compilation time.
In one program, that I need to use in my app (using Qt) there's:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
using namespace PL;
"#"include "res/przypisania_txt.h"
MainWindow w;
w.show();
...
and when I paste the include before main, it won't compile, so i gues You can use INCLUDE inside a function ;)
Related
Suppose I have this:
// test.h
namespace test {
#define TEST_DEBUG !NDEBUG
class TestClass {
#if TEST_DEBUG
// ...
#endif
};
}
The problem is that other files that include test.h will also get the TEST_DEBUG macro, which is not ideal.
If I use #undef at the end of the header, then that means I can't use the macro in test.cpp.
What would be the best way to solve this issue?
Although I'd advise avoiding macros in C++ (eg this could be replaced with a bool parameter to the function), the simplest way to achieve this is to define TEST_DEBUG in test.cpp before including test.h, and removing it from test.h.
A #include directive is replaced by the c preprocessor similar to a "copy the contents of that file here" way. This copy is repeated each time the #include appears. This also means if there's something defined before the #include appears in one file, but that's not defined in another, then things may break in unpredictable ways (because eg one file thinks an object is bigger than another file thinks it is).
However, to give more idiomatic c++, for a compile time flag you can use bool constexprs. Alternatively, for a runtime change, if it's a class, pass a bool to the constructor to indicate the difference, a function can have an extra parameter that defaults to false, etc.
I build DLL that contains external object from 3rd party DLL with
my3rdObject->EOF()
function
But my main DLL depends from <stdio.h> lib that contains this define
#define EOF (-1)
therefore, when compiling, an error occurs
error C2059: syntax error: '('
How to solve the problem?
enter image description here
This is really bad code.
But you could workaround it by surrounding your code calling the EOF method with an #undef and #define block.
Example:
#include <My3rdObject.hpp>
#include <stdio.h>
#undef EOF
int foo()
{
My3rdObject* my3rdObject = new My3rdObject();
my3rdObject->EOF();
delete my3rdObject;
}
#define EOF (-1)
I highly recommend writing an anti corruption layer. This is simply the kind of code you don't want in your codebase.
Preferred solution: don't use stdio.h. Upgrade your C++ code from I/O in the C style to I/O in the C++ style. However, for a workaround keep reading.
But my main DLL depends from <stdio.h> lib
No, it does not. Binary files, such as DLLs, have no dependence on source files, such as headers. Rather, the code for your DLL depends on the stdio.h header. More precisely, the particular source file in question uses that header.
So move the problem to another source file.
This is not sweeping the problem under the rug, but taking advantage of modularization. Create a new source file and a new header that for now will implement a single function. The header might look like the following.
#ifndef INCLUDE_GUARD_FOR_THIS_HEADER
#define INCLUDE_GUARD_FOR_THIS_HEADER
// Make sure the class in question is declared.
// Ideally, you would use a header from the third-party library, but avoid a header
// that declares the EOF member function.
class ThirdObject;
// Declare a function to wrap EOF().
// (Drop the `const` if EOF was not declared as a const member.)
int check_eof(const ThirdObject & to_check);
#endif // INCLUDE_GUARD_FOR_THIS_HEADER
This header can be included without inteference from stdio.h. The corresponding source file would also avoid interference by not including stdio.h. As long as you don't have a macro definition of EOF available in this source file, there is no problem.
#include "the_above_header.h"
#include <ThirdParty>
int check_eof(const ThirdObject & to_check)
{
return to_check.EOF();
}
Keep in mind that this function takes a reference, while the code in the question implies a pointer is being used. So the code from the question would become
check_eof(*my3rdObject);
Problem solved by rename "EOF" method to "EOF1" in *.idl file !
Details here: https://imgur.com/a/95wJsQE
Thanks to everyone who responded and helped!
I have the following problem:
I'm writing a collection library for a bunch of sensors to be used with a microcontroller. Meaning I take a lot of libraries for sensors and abstract and simplify them a bit in a unified library for a student project.
I use #define structures to figure out which sensors the students want to use and connected.
Example:
#define IR_SENSOR_USED
In the .h and .cpp files of the library I then use #ifdef-#endif pairs to define and declare the functions for the given sensor as well as include the given libraries.
Example from my Sensors.h file:
#ifdef IR_SENSOR_USED
#include "SparkFun_GridEYE_AMG88/src/SparkFun_GridEYE_Arduino_Library.h"
extern GridEYE grideye;
void setup_ir_sensor();
void read_ir_sensor();
void enable_ir_interrupt(float lower, float upper, float hysteresis);
void disable_ir_interrupt();
#endif
and from my Sensors.cpp file:
#ifdef IR_SENSOR_USED
void setup_ir_sensor() {
Wire.begin(16, 17, 0x69);
grideye.begin(0x69, Wire);
}
void read_ir_sensor() {
for (int i = 0; i <= 64; i++) {
sensor_values.ir_pixel_temp[i] = grideye.getPixelTemperature(i);
}
sensor_values.ir_device_temp = grideye.getDeviceTemperature();
}
void enable_ir_interrupt(float lower, float upper, float hysteresis) {...}
void disable_ir_interrupt() {...}
#endif
However, so long as I have the #ifdef in the .cpp file, I get the following error if I try to call the function in the setup():
sketch/Sensors.ino.cpp.o:(.literal._Z5setupv+0xc): undefined reference to `read_ir_sensor()'
sketch/Sensors.ino.cpp.o: In function `setup()':
.../Sensors/Sensors.ino:112: undefined reference to `read_ir_sensor()'
collect2: error: ld returned 1 exit status
exit status 1
If I comment them out, the code executes fine. Another function (setup_sensors()), which is also in the Sensors.h and .cpp files and is not surrounded by an #ifdef works also fine.
This is my Sensors.ino sketch:
#define IR_SENSOR_USED
//#define COLOR_SENSOR_USED
//#define ENV_SENSOR_USED
//#define TEMP_SENSOR_USED
#include "Sensors.h"
void setup() {
sensor_setup();
read_ir_sensor();
}
void loop() {
}
What's the reason for this? (Why) does the preprocessor not execute the directives in the .cpp file properly?
As the comments and other answer pointed out, any #define directives are only visible in the files that contain them. So having
#define IR_SENSOR_USED
in Sensors.cpp won't affect any code that's not compiled in Sensors.cpp (importantly, it will affect code that's contained in .h files that are included in Sensors.cpp after the #define. But it wouldn't affect anything contained in a different .cpp file.
More sophisticated build environments than Arduino have better and more complicated ways to deal with this problem, but the Arduino world doesn't give you a lot of tools to handle this.
What I do in the Arduino world is simply have a file called config.h which contains all the #define statements that I need project-wide. I #include "config.h" in each file that needs these values.
So in your case, you'd put your all the defines that show which devices are used in config.h and then #include "config.h" at the start of every file that depends on it.
You could even include it at the start of your Sensors.h file. I'd consider keeping the two files separate so that there would be a clear boundary between the stuff that needs to be configured and the stuff that's useful code.
I also keep any sensitive values (wifi credentials, passwords, API keys) in this file, and exclude it from code I publish on Github. In its place I include a "config-example.h" file with all the directives in it but with dummy values, so that others using the code can edit and rename it.
This question might be an instance of an XY problem.
If you would like the users of library to pick the functionality they need it would make more sense to put declarations in separate headers. E.g., IR_sensor.h and then
#define IR_SENSOR_USED
#include "Sensors.h"
becomes just #include "IR_sensor.h".
If the size of the library is or concern, splitting it into separate libraries is an option.
The third option is to provide the functionality as a header-only library.
Exact answer:
What's the reason for this? (Why) does the preprocessor not execute
the directives in the .cpp file properly?
The most likely reason is that Sensors.cpp is unaware of #define IR_SENSOR_USED. Define is in another file that is not included.
However even if IR_SENSOR_USED would be defined in the Sensors.cpp another problem arises: re-compilation of Sensors.cpp for every possible combination of defines is necessary. Otherwise the ifdefed-code is excluded from compilation and can't be simply enabled on the client side by calling #define.
Is the #include <file> meant to be used for headers only or is it simply a mechanical "inject this code here" that can be used anywhere in the code?
What if I use it in the middle of a cpp function to just "inject" code from a single source? will this work or will compilers scream about this?
It is a mechanical inject the code here device. You can include a text file containing Goethe's Faust if you wish to. You can put it anywhere, even in the middle of a function (of course, #include needs a fresh line!).
However, it's strong convention to only use #include for header files. There may be reasons where I wouldn't object on it, for example pulling in machine-generated code or merging all translation units in a single file.
Not only does it work anywhere, but it can lead to some interesting techniques. Here's an example that generates an enumeration and a corresponding string table that are guaranteed to be in sync.
Animals.h:
ANIMAL(Anteater)
ANIMAL(Baboon)
...
ANIMAL(Zebra)
AnimalLibrary.h:
#define ANIMAL(name) name,
enum Animals {
#include "Animals.h"
AnimalCount
};
#undef ANIMAL
extern char * AnimalTable[AnimalCount];
AnimalLibrary.cpp:
#include "AnimalLibrary.h"
#define ANIMAL(name) #name,
char * AnimalTable[AnimalCount] = {
#include "Animals.h"
};
main.cpp:
#include "AnimalLibrary.h"
int main()
{
cout << AnimalTable[Baboon];
return 0;
}
Be sure not to put the usual include guards in any file that will be included multiple times!
Gotta agree with William Pursell though that this technique will have people scratching their heads.
Compilers will not complain, but everyone who has to maintain the code will.
It will work - more or less its semantic meaning is: place code in that file here
EDIT: For abusing usages of #include I can just recommend the following:
#include "/dev/console"
This allows for everything: a one-liner that can do everything, an error, its just a matter of compilation...
Should work, it's processed by your preprocessor, your compiler won't even see it.
#include and other preprocessor directives like #define or #import, can appear anywhere in the source, but will only apply to the code after that inclusion. It is meant to include the referenced code into the source file that calls it.
This MSDN page explains it quite well. http://msdn.microsoft.com/en-us/library/36k2cdd4(v=VS.71).aspx
include is handled by the preprocessor and is a mechanism to inject code. There are no restrictions on the file being included or where this #include is placed in your code (thought it should be in its own line). As long as the file specified can be found by the preprocessor it will import its contents into the current file.
Conventionally you do this for header files. I've seen this being done with cpp files during template instantiation (with proper #ifdef so you don't include it multiple times causing multiple symbol definition error).
If you have a long constant, you can do this for other file types as well. (Though there are better ways of handling long string constants)
Instead of doing
#include "MyClass.cpp"
I would like to do
#include "MyClass.h"
I've read online that not doing so is considered bad practice.
Separate compilation in a nutshell
First, let's get some quick examples out there:
struct ClassDeclaration; // 'class' / 'struct' mean almost the same thing here
struct ClassDefinition {}; // the only difference is default accessibility
// of bases and members
void function_declaration();
void function_definition() {}
extern int global_object_declaration;
int global_object_definition;
template<class T> // cannot replace this 'class' with 'struct'
struct ClassTemplateDeclaration;
template<class T>
struct ClassTemplateDefinition {};
template<class T>
void function_template_declaration();
template<class T>
void function_template_definition() {}
Translation Unit
A translation unit (TU) is a single source file (should be a **.cpp* file) and all the files it includes, and they include, etc. In other words: the result of preprocessing a single file.
Headers
Include guards are a hack to work around lack of a real module system, making headers into a kind of limited module; to this end, including the same header more than once must not have an adverse affect.
Include guards work by making subsequent #includes no-ops, with the definitions available from the first include. Because of their limited nature, macros which control header options should be consistent throughout a project (oddball headers like <assert.h> cause problems) and all #includes of public headers should be outside of any namespace, class, etc., usually at the top of any file.
See my include guard naming advice, including a short program to generate include guards.
Declarations
Classes, functions, objects, and templates may be declared almost anywhere, may be declared any number of times, and must be declared before referring to them in any way. In a few weird cases, you can declare classes as you use them; won't cover that here.
Definitions
Classes may be defined at most once[1] per TU; this typically happens when you include a header for a particular class. Functions and objects must be defined once in exactly one TU; this typically happens when you implement them in a **.cpp* file. However, inline functions, including implicitly inline functions inside class definitions, may be defined in multiple TUs, but the definitions must be identical.
For practical purposes[2], templates (both class templates and function templates) are defined only in headers, and if you want to use a separate file, then use another header[3].
[1] Because of the at-most-once restriction, headers use include guards to prevent multiple inclusion and thus multiple definition errors.
[2] I won't cover the other possibilities here.
[3] Name it blahblah_detail.hpp, blahblah_private.hpp, or similar if you want to document that it's non-public.
Guidelines
So, while I'm sure everything above is all a big ball of mud so far, it's less than a page on what should take up a few chapters, so use it as a brief reference. Understanding the concepts above, however, is important. Using those, here's a short list of guidelines (but not absolute rules):
Always name headers consistently in a single project, such as **.h* for C and **.hpp* for C++.
Never include a file which is not a header.
Always name implementation files (which are going to be directly compiled) consistently, such as **.c* and **.cpp*.
Use a build system which can compile your source files automatically. make is the canonical example, but there are many alternatives. Keep it simple in simple cases. For example, make can be used its built-in rules and even without a makefile.
Use a build system which can generate header dependencies. Some compilers can generate this with command-line switches, such as -M, so you can make a surprisingly useful system easily.
Build Process
(Here's the tiny bit that answers your question, but you need most of the above in order to get here.)
When you build, the build system will then go through several steps, of which the important ones for this discussion are:
compile each implementation file as a TU, producing an object file (**.o*, **.obj*)
each is compiled independently of the others, which is why each TU needs declarations and definitions
link those files, along with libraries specified, into a single executable
I recommend you learn the rudiments of make, as it is popular, well-understood, and easy to get started with. However, it's an old system with several problems, and you'll want to switch to something else at some point.
Choosing a build system is almost a religious experience, like choosing an editor, except you'll have to work with more people (everyone working on the same project) and will likely be much more constrained by precedent and convention. You can use an IDE which handles the same details for you, but this has no real benefit from using a comprehensive build system instead, and you really should still know what it's doing under the hood.
File Templates
example.hpp
#ifndef EXAMPLE_INCLUDE_GUARD_60497EBE580B4F5292059C8705848F75
#define EXAMPLE_INCLUDE_GUARD_60497EBE580B4F5292059C8705848F75
// all project-specific macros for this project are prefixed "EXAMPLE_"
#include <ostream> // required headers/"modules"/libraries from the
#include <string> // stdlib, this project, and elsewhere
#include <vector>
namespace example { // main namespace for this project
template<class T>
struct TemplateExample { // for practical purposes, just put entire
void f() {} // definition of class and all methods in header
T data;
};
struct FooBar {
FooBar(); // declared
int size() const { return v.size(); } // defined (& implicitly inline)
private:
std::vector<TemplateExample<int> > v;
};
int main(std::vector<std::string> args); // declared
} // example::
#endif
example.cpp
#include "example.hpp" // include the headers "specific to" this implementation
// file first, helps make sure the header includes anything it needs (is
// independent)
#include <algorithm> // anything additional not included by the header
#include <iostream>
namespace example {
FooBar::FooBar() : v(42) {} // define ctor
int main(std::vector<std::string> args) { // define function
using namespace std; // use inside function scope, if desired, is always okay
// but using outside function scope can be problematic
cout << "doing real work now...\n"; // no std:: needed here
return 42;
}
} // example::
main.cpp
#include <iostream>
#include "example.hpp"
int main(int argc, char const** argv) try {
// do any global initialization before real main
return example::main(std::vector<std::string>(argv, argv + argc));
}
catch (std::exception& e) {
std::cerr << "[uncaught exception: " << e.what() << "]\n";
return 1; // or EXIT_FAILURE, etc.
}
catch (...) {
std::cerr << "[unknown uncaught exception]\n";
return 1; // or EXIT_FAILURE, etc.
}
This is called separate compilation model. You include class declarations into each module where they are needed, but define them only once.
In addition to hiding implementation details in cpp files (check other replies), you can additionally hide structure details by class forward declaration.
class FooPrivate;
class Foo
{
public:
// public stuff goes here
private:
FooPrivate *foo_private;
};
The expression class FooPrivate says that FooPrivate is completely defined somewhere else (preferably in the same file where Foo's implementation resides, before Foo's stuff comes. This way you make sure that implementation details of Foo(Private) aren't exposed via the header file.
You needn't include .c or .cpp files - the compiler will compile them regardless whether they're #included in other files or not. However, the code in the .c/.cpp files is useless if the other files are unaware of the classes/methods/functions/global vars/whatever that's contained in them. And that's where headers come into play. In the headers, you only put declarations, such as this one:
//myfile.hpp
class MyClass {
public:
MyClass (void);
void myMethod (void);
static int myStaticVar;
private:
int myPrivateVar;
};
Now, all .c/.cpp files that will #include "myfile.hpp" will be able to create instances of MyClass, operate on myStaticVar and call MyClass::myMethod(), even though there's no actual implementation here! See?
The implementation (the actual code) goes into myfile.cpp, where you tell the compiler what all your stuff does:
//myfile.cpp
int MyClass::myStaticVar = 0;
MyClass::MyClass (void) {
myPrivateVar = 0;
}
void MyClass::myMethod (void) {
myPrivateVar++;
}
You never include this file anywhere, it's absolutely not necessary.
A tip: create a main.hpp (or main.h, if you prefer - makes no difference) file and put all the #includes there. Each .c/.cpp file will then only need to have have this line: #include "main.hpp". This is enough to have access to all classes, methods etc. you declared in your entire project :).
You should not include a source file (.c or .cpp). Instead you should include the corresponding header file(.h) containing the declarations. The source files needs to be compiled separately and linked together to get the final executable.
Cpp files should be defined in your compiler script to be compiled as object files.
What ide are you using?
I am going to assume you are compiling with gcc, so here is the command to compile two .cpp files into one executable
gcc -o myclasses.out myclass.cpp myotherclass.cpp
You should only use #include to include class definitions, not the implentation
One thing you will want to watch out for when including you class declarations from a .h/.hpp is make sure it only ever gets included once. If you don't do this you will get some possibly cryptic compiler errors that will drive you up the wall.
To do this you need to tell the compiler, using a #define, to include the file only if the #define does not already exist.
For example (MyClass.h):
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
// Memebers and methods
}
#endif
// End of file
This will guarantee your class declaration only gets included once even if you have it included in many different .cpp files.