h1

Simple guide to basic Doxygen usage

July 20, 2008

Make sure to also check out part 2 of this tutorial, “Simple Doxygen templates” for many useful templates and tips.

This is a simple guide to basic use of Doxygen-compliant commenting of source code. The guide is written from my point – C/C++ – but it’s valid for all supported languages, except of Python. See Doxygen documentation for use for Python. Doxygen is very flexible when it comes to the form of how the documentation is written, the layout presented here is simply my preference.

Doxygen is a documentation system for C/C++, Java, Objective-C, Python, IDL (Corba and Microsoft flavors) and to some extent PHP, C#, and D.

Installation and setup is very simple for all supported systems, and with Doxywizard, setting up the project of documentation is very simple also.

The harder part is converting the old in-code documentation to Doxygen-compliant one.

Basicly, Doxygen documentation of any “object” (file, function, class, …) consists of brief and detailed description, as follows:

//! Brief description, can span only 1 line
/*!
 * More detailed description.
 * Feel free to span as many lines
 * as you wish... All allowed.
 */

Doxygen supports also in-line comments (comments on the same line as the documented piece of code), both brief and detailed kind; these blocks can only be used to document members and parameters!

void HelpFn1();    //!< Internal.
void HelpFn2();    /*!< Internal. */

Be careful using these though, since it’s easy to make a mistake:

void function1();    //!< Correct
void function2(int i);    //!< WRONG! Comment on parameter i, but function not documented!

//! Some other function.
void function3(int i);    //!< Some int. Correct - both function and parameter documented

Doxygen allows you to document also various aspects of “objects”, for instance:

//! Copy a string.
/*!
 * The strcpy function copies \a strSource, including
 * the terminating null character, to the location
 * specified by \a strDestination. No overflow checking
 * is performed when strings are copied or appended.
 * The behavior of \a strcpy is undefined if the source
 * and destination strings overlap.
 *
 * \param strSource pointer to source null terminated string
 * \param strDestination pointer to destination memory
 * \return \a strcpy returns the destination string.
 * No return value is reserved to indicate an error.
 * \sa wcscpy(), _mbscpy(), strncpy()
 */
char* strcpy(char* strDestination, const char* strSource);

Notice how \a is used to tell doxygen, that strSource and strDestination refer to parameters. The \sa contains the “see also” section of documentation.

Documentation in other places

Doxygen allows you to put your documentation blocks practically anywhere (the exception is inside the body of a function or inside a normal C style comment block).
To do so, you need to put a structural command inside the documentation block.

\class to document a C++/Java class
\struct to document a C-struct.
\union to document a union.
\enum to document an enumeration type.
\fn to document a function.
\var to document a variable or typedef or enum value.
\def to document a #define (macros).
\typedef to document a type definition.
\file to document a file.
\namespace to document a namespace.
\package to document a Java package.
\interface to document an IDL interface.

For instance, if you want to document the class Test, put the following documentation block somewhere in the input that is read by doxygen:

/*! \class Test
 * \brief A test class.
 *
 * A more detailed class description.
 */

BEWARE: To document a member of a C++ class, you must also document the class itself. The same holds for namespaces. To document a global C function, typedef, enum or preprocessor definition you must first document the file that contains it (usually this will be a header file, because that file contains the information that is exported to other source files).

/*! \file myheader.h
 * \brief A Documented header file.
 *
 * Details about myheader.h.
 */

/*! \def MAX(a,b)
 * \brief A macro that returns the maximum of \a a and \a b.
 *
 * Details.
 */

/*! \var typedef unsigned int UINT32
 * \brief A type definition for unsigned int.
 *
 * Details.
 */

/*! \var int errno
 * \brief Contains the last error code.
 *
 * \warning Not thread safe!
 */

/*! \fn int close(int fd)
 * \brief Closes the file descriptor \a fd.
 * \param fd The descriptor to close.
 */

#define MAX(a,b) (((a) > (b)) ? (a) : (b))
typedef unsigned int UINT32;
int errno;
int close(int);

Part 2 is now out! Check out “Simple Doxygen templates” for templates of sample Doxygen block comments, and many small tips…

8 comments

  1. [...] July 23. 2008 Josef Nygrin has written a fantastic guide to Doxygen, which is a documentation system for C, C++, Objective-C, Python, Java and a number of other [...]


  2. Thanks – you’ve just shown me why I couldn’t get my damned enums to show up in the doxygen output (the namespace hadn’t been documented yet). Lifesaver :)


  3. I’m glad I could help! :)

    Cheers!


  4. I use the rth output.
    I wonder how to control the order that doxygen do the docomentaion.
    I want documents for file main.c will appear before file comunication.c
    Thank in advanced
    David


  5. As far as I know, there is no way to do that other than manual re-arangement after the documentation is generated…
    IMO – Doxygen simply goes through all files in directory and generates documentation; I didn’t find any way to mark a file as “prefered”.

    The only choice of sorting in Doxygen I know of is sorting of detailed and brief descriptions (via SORT_MEMBER_DOCS and SORT_BRIEF_DOCS tags).

    Sorry, and thanks for visit! :)


  6. Thank you for helping me improve the documentation for CartoType. Like many people I couldn’t get enums to show up in my main namespace. This is a Doxygen flaw in my opinion: there is no reason why it should not be able to document members of enclosing things like classes and namespaces that are not themselves documented.


  7. Glad I could help! :)

    The problem has two sides – it sure is confusing, why the enclosed members cannot appear “by themselves”, but on the other hand, enclosed members without the context of the enclosing class (…) don’t make much sense.


  8. [...] is another interested reading for interested ones:  http://justcheckingonall.wordpress.com/2… Posted by saurabh Filed in [...]



Leave a Comment