Our C++ program has a built-in script interface and is able to run scripts in it. The scripts have access to convenience functions provided by the C++ program.
Now we would like Doxygen to create the documentation of the functions the script has access to. Such a function declaration looks like this:
void ScriptEngine::load_script(const QString &path) {
//...
/*! \fn sleep_ms(const unsigned int timeout_ms)
\brief sleeps for timeout_ms milliseconds.
\param timeout_ms
*/
(*lua)["sleep_ms"] = [](const unsigned int timeout_ms) {
//sleep(timeout_ms)
};
//more convenience functions..
//...
}
Obviously Doxygen won't include a
sleep_ms(const unsigned int timeout_ms)
into the documentation. Is there a way to to tell Doxygen to do so?
Do this:
Add the following line to your Doxyfile:
PREDEFINED = _DOXYGEN_
Make sure the ENABLE_PREPROCESSING tag in the Doxyfile is set to YES.
Put your declarations and documentation for the undeclared functions inside an #ifdef _DOXYGEN_ section.
#ifdef _DOXYGEN_
/*! \fn sleep_ms(const unsigned int timeout_ms)
\brief sleeps for timeout_ms milliseconds.
\param timeout_ms
*/
void sleep_ms(const unsigned int timeout_ms);
#endif
Don't put the above code inside a method or function such as ScriptEngine::load_script(), as you previously tried. And don't put it inside a namespace or class, unless in fact the function being declared is a member of that namespace or class.
With this method, your declarations will not create linker errors during a normal build, but will be seen by Doxygen.
See Also
http://www.doxygen.nl/manual/config.html#cfg_predefined
Related
I am trying to properly declare and define global variables in separate files and include them in a third file which deals with class declaration.
The three files are:
1) global.h
#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED
extern const int marker_num;
extern const int dim;
using namespace std;
#endif // GLOBAL_H_INCLUDED
2) global.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include "global.h"
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
constexpr const int marker_num = 10;
constexpr const int dim = (2 * marker_num) + 3;
3) WorldState.h
#ifndef WORLDSTATE_H
#define WORLDSTATE_H
#include "global.h"
#include "global.cpp"
class WorldState{
public:
WorldState(float a[], float b[dim][dim]);
get_wstate();
protected:
private:
float w_state[];
float covar_matrix[dim][dim];
};
#endif // WORLDSTATE_H
I am using the global variable dim to declare and define a multidimensional array. I have declared dim inside global.h and defined it inside global.cpp. Now, I have a class called WorldState and inside its header, I am using dim. If I comment out #include "global.cpp", it throws the following error:
C:\Users\syamp\Documents\codeblocks\slam\WorldState.h|10|error: array bound is not an integer constant before ']' token
My understanding is that including the .h file includes the corresponding .cpp as well, and that all declarations should be inside .h and all definitions should be inside .cpp. However, it doesn't seem to work in this case.
1) If I decide to include global.cpp file inside WorldState.h, isn't it bad programming practice? I am trying to write a good code not just a code that works.
2) An alternative is to define values of variable(s) dim (and marker_num) inside global.h. Is that good programming practice?
3) I believe there is something that I am missing. Kindly suggest the best method to resolve this issue. I am using codeblocks and C++11. Thanks in advance.
I am using the global variable dim to declare and define a multidimensional array.
When declaring a fixed-length array at compile-time, the value(s) of its dimension(s) must be known to the compiler, but your separation prevents the value of dim from being known to the compiler at all, so dim cannot be used to specify fixed array dimensions. Any code that uses dim will just compile into a reference to it, and then the linker will resolve the references after compilation is done. Just because dim is declared as const does not make it suitable as a compile-time constant. To do that, you must define its value in its declaration, eg:
#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED
static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num);
using namespace std;
#endif // GLOBAL_H_INCLUDED
Otherwise, if you keep dim's declaration and definition in separate files, you will have to dynamically allocate the array at run-time instead of statically at compile-time.
I have declared dim inside global.h and defined it inside global.cpp.
That is fine for values you don't need to use until run-time. That will not work for values you need to use at compile-time.
My understanding is that including the .h file includes the corresponding .cpp as well
That is not even remotely true. The project/makefile brings in the .cpp file when invoking the compiler. The .h file has nothing to do with that.
that all declarations should be inside .h and all definitions should be inside .cpp.
Typically yes, but not always.
If I decide to include global.cpp file inside WorldState.h, isn't it bad programming practice?
Yes.
An alternative is to define values of variable(s) dim (and marker_num) inside global.h. Is that good programming practice?
Yes, if you want to use them where compile-time constants are expected.
I want to generate documentation only for code that has Doxygen comments. I have created a Doxyfile via Doxygen version 1.8.9.1 and configured it to output only XML and to hide all undocumented code:
GENERATE_HTML = NO
GENERATE_LATEX = NO
GENERATE_XML = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
After that I created a simple C header test.h with one documented and one non-documented function declaration:
void foo(int a);
/**
* "bar" function description
* #param b sample param
*/
void bar(int b);
By executing doxygen I expected only documentation for bar to be included in the resulting XML. Unfortunately, documentation for both functions is generated. Is it possible to generate documentation only for code that has Doxygen comments? Or will Doxygen always include everything in the XML output regardless of settings?
Before reading any further make sure EXTRACT_ALL is set to NO.
I'm not a fan of the following solution but it does work. Use doxygen's preprocessor
#ifdef PROJECT_NO_DOC
void foo(int a);
#endif /* PROJECT_NO_DOC */
/**
* * "bar" function description
* * #param b sample param
* */
void bar(int b);
Note, in their docs you have to set a PREDEFINED macro but at least in my version of doxygen this was not required. Their docs specify to do it this way set a predefined macro in the config to do it for you
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* code that must be skipped by Doxygen */
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
around the blocks that should be hidden and put:
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
in the config file then all blocks should be skipped by doxygen as long as
ENABLE_PREPROCESSING = YES
There are other methods but they come with additional constraints ie to make sure no static method appear in your public docs you can set EXTRACT_STATIC to NO.
You can use \cond to hide parts of the source code from Doxygen. This avoids the need to use the preprocessor as in Harry's answer.
For example, here foo will not be seen by Doxygen, and hence not documented:
/** \cond */
void foo(int a);
/** \endcond */
/**
* "bar" function description
* #param b sample param
*/
void bar(int b);
Furthermore, it is possible to add section labels to \cond, and control which sections are included by listing them in the ENABLED_SECTIONS configuration option.
For example:
/// \cond CLASS_A
/// This function foos `a`.
void foo(int a);
/// \endcond
/// \cond CLASS_B
/// This function bars `b`.
void bar(int b);
/// \endcond
By setting ENABLED_SECTIONS = CLASS_A CLASS_B, both functions will show up in the documentation. Leaving one of the labels out will hide the corresponding function.
I'm investigating the Linux kernel where I came across multiple functions that have the following syntax. I'm confused about what this syntax means. I'm not interested what the function does, but what the syntax means.
static int __init customize_machine(void)
{
...
return 0;
}
Here, __init is a macro. It says return 0, so it returns an int, but what is the __init macro doing there?
Also, the macros are found at the end of the function name declaration:
static noinline void __init_refok rest_init(void) __releases(kernel_lock)
{
...
}
Same question: what is the purpose of this macro?
This function is a part of a linux kernel module. The __init macro can be found in linux/module.h. Use it like module_init(customize_machine) and becomes the init function of the module. Returning 0 means the module is loaded successfully.
If I missed the prototype, XCode (LLVM) prompt me for error
no previous prototype for function for exceptionHandler
But why they are needed in my code below?
void exceptionHandler(NSException * exception); // Why this Line is needed?
void exceptionHandler(NSException * exception)
{
// ....
}
#implementation AppDelegate
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
NSSetUncaughtExceptionHandler(&exceptionHandler);
...
From the GCC manual:
-Wmissing-prototypes (C and Objective-C only)
Warn if a global function is defined without a previous prototype declaration. This warning is issued even if the definition itself provides a prototype. The aim is to detect global functions that fail to be declared in header files.
Clang borrowed this option for GCC compatibility, and because it's useful (I would presume this of the Clang devs).
The option exists so you can prevent yourself from making a common mistake which may be easily avoided. It's nice to be explicit about visibility/linkage for clarity/intent's sake.
In short, you've asked the compiler to tell you when an unqualified definition does not match a declaration by enabling this option. You should either qualify that as extern and make it usable to others (e.g. put it in a header), or declare it static. If using C++ inline is also an option.
Of course, implicit visibility is well known, but I typically find the option useful in these scenarios:
1) I made a typo:
// file.h
extern void MONExceptionHandler(NSException * exception);
and
// file.m
void MONExceptionhandler(NSException * exception) {
…
2) I should be explicit about the symbol's visibility:
// file.m
static void MONExceptionHandler(NSException * exception) {
…
3) I forgot to #include the header which declared the function:
// file.h
extern void MONExceptionHandler(NSException * exception);
Warning:
// file.m
void MONExceptionHandler(NSException * exception) {
…
No Warning:
// file.m
#include "file.h"
void MONExceptionHandler(NSException * exception) {
…
So there's the rationale, history, and some examples - again, -Wmissing-prototypes is an option. If you trust yourself to work with it disabled, then do so. My preference is to be explicit, and to let programs detect potential and actual issues so I don't have to do it manually.
If you're declaring a function only for use within this file, prefix the declaration with the static keyword and the warning will go away. As it is, you're declaring a global function; theoretically it could be called from anywhere within your app. But as you've given it no prototype, nobody else could call it.
So the warning, as I understand it, is trying to make you clarify your intentions between static functions and global functions, and discourage you from declaring a global function when you meant to declare only a static one.
I think this is most useful for C++ code. For example I have header
class MyClass {
public:
void hello();
};
and .cpp file
void hello() {
cout << "hello";
}
And you will see the warning because there are no prototype for function void hello(). In case the correct implementation should be
void MyClass::hello() {
cout << "hello";
}
So this warning make sure you are implementing the function that you are aware of (not miss typed a name or different argument format).
That warning is alerting that you can't call your method from another method that is written above. In C, the order of the declaration/implementation minds a lot and gives the difference between something that you can access or you can't.
I have a code
static const guint8 variable;
when I put a documentation
/**
* \var static const guint8 variable;
* \brief This is a variable
*/
static const guint8 variable;
I do not get any output in the generated documentation. However, when the same thing is done with a simple variable decleration:
/**
* \var int someothervar;
* \brief This is some other variable
*/
int variable;
it does work
is that I am making some mistake in the usage ?
Thanks for any help in advance,
- elechi
For extracting static variables you should set EXTRACT_STATIC to YES.
If the documentation is in front of the variable, you do not need (and should not use) \var
Either set EXTRACT_ALL to YES or add a comment with a #file command in your code to document the file itself.