如何记录未定义的预编译标志

时间:2017-11-28 17:15:24

标签: c undefined doxygen

我有C代码我想用doxygen记录。 C代码是一个代码块,可以由不同的应用程序接收。在编译时,这些应用程序通过定义特定的宏(或通过定义它们)来改变代码块的功能。

例如,请使用此文件block.c

int Block_DoPlus(int x, int y)
{
#if defined(DO_EXTRAPLUS)
    return x + y + y;
#else
    return x + y;
#endif
}

int Block_DoMinus(int x, int y)
{
#if defined(DO_EXTRAMINUS)
return x - y - y;
#else
return x - y;
#endif
}

记录这些未定义的预编译标记DO_EXTRAPLUSDO_EXTRAMINUS的最佳方法是什么?

  • 我希望它们看起来与其他标记和令牌很好的标记相同
  • 我想同样允许我的代码用户有条件地定义回调,我只看到#undef作为合理选项。
  • 我想使用define而不是getters / setter来最小化代码(想想大)。

选项1 block.h - 不起作用; DO_EXTRAPLUSDO_EXTRAMINUS未在生成的html中显示

#ifndef __BLOCK_H__
#define __BLOCK_H__
/** @defgroup BLOCK A block of code
 * gcc this code with -dDO_EXTRAPLUS and/or -dDO_EXTRAMINUS
 * @{
 */

/** Does extra plus */
#ifndef DO_EXTRAPLUS
#   undef DO_EXTRAPLUS
#endif

/** Does extra minus */
#ifndef DO_EXTRAMINUS
#   undef DO_EXTRAMINUS
#endif

/** Does plus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoPlus(int x, int y);

/** Does minus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoMinus(int x, int y);
#endif /** @} */

选项2 block.h - 有效,但在代码中看起来很愚蠢

#ifndef __BLOCK_H__
#define __BLOCK_H__
/** @defgroup BLOCK A block of code
 * gcc this code with -dDO_EXTRAPLUS and/or -dDO_EXTRAMINUS
 * @{
 */

/** Does extra plus */
#ifndef DO_EXTRAPLUS
#   define DO_EXTRAPLUS
#   undef DO_EXTRAPLUS
#endif

/** Does extra minus */
#ifndef DO_EXTRAMINUS
#   define DO_EXTRAMINUS
#   undef DO_EXTRAMINUS
#endif

/** Does plus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoPlus(int x, int y);

/** Does minus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoMinus(int x, int y);

#endif /** @} */

选项3 block.h - 工作,但在html文件中看起来很愚蠢,而且以后您无法引用DO_EXTRAPLUS ::(或#),仅限于\ref

#ifndef __BLOCK_H__
#define __BLOCK_H__
/** @defgroup BLOCK My fancy block of code
 * gcc this code with -dDO_EXTRAPLUS and/or -dDO_EXTRAMINUS
 * 
 * @anchor DO_EXTRAPLUS
 * @par #define DO_EXTRAPLUS
 *  Does plus
 *  
 * @anchor DO_EXTRAMINUS
 * @par #define DO_EXTRAMINUS
 *  Does minus
 * @{
 */

/** Does plus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoPlus(int x, int y);

/** Does minus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoMinus(int x, int y);

#endif /** @} */ 

选项4 :???

2 个答案:

答案 0 :(得分:1)

我选择选项0:不要使用编译器标志进行配置。使用全局变量(或者更好的是配置对象中的变量)。

  • 正如您所发现的那样,编译器标记很难记录。

  • 编译器标志不能在运行时更改。

  • 编译器标志在可执行文件中共享。没有(简单)方法可以使用一个应用程序,其中一部分应用程序使用您的代码和一组编译器标志,另一部分使用不同的标志。

  • 编译器标志与构建代码作为库不兼容。 (我的意思是,你可以将代码构建为库,但是你必须选择在构建时使用哪些标志。图书馆的消费者别无选择。)< / p>

  • 编译器标志与代码测试不兼容:

    • 大多数测试框架假设您的代码可以编译一次,然后通过以不同方式调用它来进行测试 - 当代码的某些部分仅在使用某些编译器标记构建时才可访问,这变得不可能。

    • 如果您的代码甚至有适量的编译器标志,则无法测试所有组合。您最终会遇到某些标志集可能永远不会被测试的情况,并且由于不同的有条件启用的代码块之间的意外交互,可能会导致意外行为(甚至编译失败!)。

答案 1 :(得分:0)

我找到的最佳解决方案:

选项4 block.h - 工作,在代码和html中看起来都不错

#ifndef __BLOCK_H__
#define __BLOCK_H__
/** @defgroup BLOCK A block of code
 * @{
 */

/* Flags below are undefined by default.
 * They are wrapped in a DOXYGEN precompilation flag to enable
 * documenting them properly.
 */
#ifdef __DOXYGEN__
#error This block of code may not be parsed using gcc.

/** Does extra plus */
#define DO_EXTRAPLUS When defined, changes behavior of Block_DoPlus

/** Does extra minus */
#define DO_EXTRAMINUS When defined, changes behavior of Block_DoMinus

#endif

/** Does plus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoPlus(int x, int y);

/** Does minus
 * @param x : x is ickx
 * @param y : y is why
 */
int Block_DoMinus(int x, int y);

#endif /** @} */

加号,将__DOXYGEN__添加为 doxyfile 中的预定义宏

  • 可以使用::(或#
  • 引用标记
  • 标记与其他标记一样记录
  • 解析定义后的文本并识别标记链接
  • #error指令和非doxygen注释明确解释了构造