I have a single header C/C++ library which contains different inline functions whether the header is included from C or C++.
#ifndef __cplusplus
// C stuff
#else
// C++ stuff
#endif
The problem is that doxygen always parses just one of the two paths depending on whether I predefine __cplusplus myself or not. Entirely disabling preprocessing is no option either as I have other macros I'd like to keep in the documentation.
Is there any sane way to generate documentation for the C and the C++ part of the header?
Related
I want to ask if I can make a file of macros that basically defined at compile time and use these macros in my c++ code which compiles specific code if the condition is true. SO what is basically the extension for that file is it a .txt file or a .h file. and how to put this file in CmakeList.txt to make it executable at compile time. for example like this in a specific file?
#define melodic 1
#define noetic 2
A C++ macro is a shortcut for writing code, what happens when you compile your project is that this code:
#define SOMETHING 32
int i = SOMETHING
Is changed to before it is compiled:
int i = 32
So a macro just substitutes text wherever you place it. There is also another use of macros that maybe is what you are looking for. You can use the preprocessing directive #ifdef MACRO to compile some code conditionally. For example, let's say that you have a function that is only there for debugging, but you don't want that code to make it to release. You could define it like:
void hello() {
#ifdef DEBUG
print("debug");
#endif
}
Then, if that file has a #define DEBUG before the #ifdef macro, the code will be included. Otherwise, the code will be discarded. Note that to use #ifdef the macro body may be empty or not, it just checks if the defined directive was used.
What you might want to accomplish is to have a series of preprocessor macros that you either set or don't in a separate configuration file to change the code produced. They are a very powerful tool, but they must be use with caution since having too many can make code not very readable.
To accomplish that, you need to include the #define MACRO in the same file that you are checking if it is defined, and before you check it. If you are only using that macro in that file, it would be good to place it at the top of it, but if you use it on multiple files you can create a header file (.h) and use #include "name.h", since include copies the contents of the header file there, therefore adding the macro definitions to your file.
The preprocessor directives are dependent on the compiler, so the version and type of compiler you use (gcc, clang...) will have different support for them. However, defined and ifdef are very widely spread and most if not all compilers have them. I recommend reading more about directives, for example here.
Finally, in case you go the route of the .h file, you would add it like any other header file you have in your project to the CmakeList.txt.
I have a C++ code which needs to include a certain library in some servers and not in other servers. I build my code using bjam.
Code example:
if server in server_list:
include <header-file.h>
int function();
else:
int function();
And during build using bjam:
if server in server_list:
-llibrary
else:
...
Header file inclusion is a compile time activity not run time. So you can't use if conditions for the same
use #ifdefs
#define SERVER_IN_LIST
#ifdef SERVER_IN_LIST
#include<...>
#endif
In C and C++ any line that begins with a # is a pre-processor directive. The pre-processor is a text parser that parses a source code file before it is compiled. It understands particular directives such as #include, #define and #ifdef but it treats normal C++ code as if it were text. For this reason, you can't use normal C++ code to alter the interpretation of the pre-processor directives.
Let's look at an example:
if (x == 4){
#include "x4.h"
}
The above is wrong because the if statement and its braces are part of the C++ code so will be ignored by the pre-processor. The pre-processor will go straight ahead and interpret the #include directive, which will cause the contents of x4.h to be pasted into that position in the file.
The correct way to write this is to use conditional pre-processor directives such as #if or #ifdef. For example...
#ifdef INCLUDE_X4
# include "x4.h"
#endif
Note that the indentation in this code is optional.
More information about pre-processor directives can be found here.
I know C or C++ code usually needs to use include guards like this:
#ifndef __A__H__
#define __A__H__
class A{
};
#endif
and to speed up compile time, in other cpp (e.g.:B.cpp), it can change
#include "A.h"
to:
#ifndef __A__H__
#include "A.h"
#endif
but the question is why doesn't the compiler automatically add or generate the include guard, and therefore why does the programmer need to add it manually if an include guard is usually required?
There are times when it is absolutely incorrect to generate the header guard. The standards contain an example: <assert.h> in C and <cassert> in C++.
The effect of reincluding those headers depends on the state of the NDEBUG macro when the header is (re)included. It is legitimate to write:
#undef NDEBUG
#include <assert.h>
…code using assert…
#define NDEBUG 1
#include <assert.h>
…more code using assert…
If the compiler automatically generated a header guard, that would not work correctly. Therefore, compilers do not generate header guards automatically.
Incidentally, user code should not use header guard macro names that start with double underscore, or underscore capital letter. Such names are reserved for the implementation. In C++, no user-defined name may legitimately contain a double underscore at all. Use something more like:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
…body of header…
#endif
The compiler, or more strictly the pre-processor cannot determine the programmer's intent in using inclusion. The compiler does not explicitly distinguish between .h files and .c or .cpp files; they differ only in the type of code one places in them. In fact the compiler deals only in a single translation unit; it is the responsibility of the C preprocessor to concatenate all included files into a single file for compilation. It would be incorrect for the pre-processor to omit an inclusion that it has previously included because it has no semantic knowledge of the code and may cause intended behaviour to change by second-guessing the developer.
In some circumstances, an IDE may add include guards for template code that it has generated. For example Microsoft Visual Studio will add them for code that it generates via its project start-up wizards. If it happens at all, it is properly the responsibility of the IDE rather than the compiler or pre-processor.
What I want to do:
I have autogenerated C Code generated with Matlab Simulink and want to enhance it with some more functionality written in C++. To be exact, the C code calls a C-style API that internally uses C++. The whole thing is in a VS 2008 C++ project.
The problem:
It compiles, as long as I tell VS to compile it as C and leave out my C++ code. As soon as I compile it as C++ problems arise.
First of all, I can't compile it as C++ because math.h produces an error C2668 due to an ambiguous call to an overloaded function (fabs()).
If I now additionally add some C++, e.g. include iostream, I get hundreds of compiler errors complaining about missing curly braces and misplaced colons somewhere in cstdlib.
My question:
How can I mix the two languages in a way that works? I read about preprocessor defines (http://www.parashift.com/c++-faq-lite/overview-mixing-langs.html) but I don't know how to apply them correctly to solve my problem.
Any help is greatly appreciated!
It seems you are including C++ headers in your C source code. Probably indirectly by including it in other header files (i.e. the C source include your C++ header, and the C++ header includes other C++ header files).
There are two ways of solving this:
Use the preprocessor to conditionally include the C++ headers only when compiled in C++. This can be done like
#ifdef __cplusplus
# include some_cpp_header
#endif
Don't include C++ headers (directly or indirectly) in your header files. Or better, make a separate header file whose only purpose is to be included in the C source, and which only contains the function prototypes (with extern "C" when compiled as C++) of the API. The body of the header file could look like this
#ifdef __cplusplus
extern "C" {
#endif
void function1(int);
int function2(const char*);
/* More function prototypes */
#ifdef __cplusplus
}
#endif
I recommend the second method.
Include the <iostream> library and then you'll have to compile your code with a c++-compiler.
Just a small question:
Can C++ use C header files in a program?
This might be a weird question, basically I need to use the source code from other program (made in C language) in a C++ one. Is there any difference between both header files in general? Maybe if I change some libraries...
I hope you can help me.
Yes, you can include C headers in C++ code. It's normal to add this:
#ifdef __cplusplus
extern "C"
{
#endif
// C header here
#ifdef __cplusplus
}
#endif
so that the C++ compiler knows that function declarations etc. should be treated as C and not C++.
If you are compiling the C code together, as part of your project, with your C++ code, you should just need to include the header files as per usual, and use the C++ compiler mode to compile the code - however, some C code won't compile "cleanly" with a C++ compiler (e.g. use of malloc will need casting).
If on, the other hand, you have a library or some other code that isn't part of your project, then you do need to make sure the headers are marked as extern "C", otherwise C++ naming convention for the compiled names of functions will apply, which won't match the naming convention used by the C compiler.
There are two options here, either you edit the header file itself, adding
#ifdef __cplusplus
extern "C" {
#endif
... original content of headerfile goes here.
#ifdef __cplusplus
}
#endif
Or, if you haven't got the possibility to edit those headers, you can use this form:
#ifdef __cplusplus
extern "C" {
#endif
#include <c_header.h>
#ifdef __cplusplus
}
#endif
Yes, but you need to tell the C++ compiler that the declarations from the header are C:
extern "C" {
#include "c-header.h"
}
Many C headers have these included already, wrapped in #if defined __cplusplus. That is arguably a bit weird (C++ syntax in a C header) but it's often done for convenience.