从编译中排除部分—仍然是语法检查

Exclude parts from compilation - still syntax-check

本文关键字:仍然是 语法 检查 编译 排除部      更新时间:2023-10-16

我们有一个非常大的c++/项目。. NET/Visual Studio,为了进行性能测试,我们包含了一些代码,可以评估某些点之间的执行时间。

PERFORMANCE_TEST BeginMeasureTime("execute someCode")
someCode
PERFORMANCE_TEST EndMeasureTime("execute someCode")

通常在开发PERFORMANCE_TEST宏时将设置为//,因此评估代码被关闭。因此,如果代码/接口等发生变化,并且PERFORMANCE_TEST宏之后的代码无效,开发人员将不会注意到。

是否有更聪明的方法使性能评估代码只构建在项目的特殊版本中,但仍然确保它保持一致?你通常是怎么做这种事的?

一个简单的方法就是修改

PERFORMANCE_TEST xxx

PERFORMANCE_TEST(xxx)

然后代替

#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST
#else
#define PERFORMANCE_TEST //
#endif

可以是

#if PERFORMANCE_TEST_ENABLED
#define PERFORMANCE_TEST(x) {x;}
#else
#define PERFORMANCE_TEST(x) if(0) { x; }
#endif

如果性能测试被禁用,优化编译器应该不为第二个版本生成代码(或者至少它不会在if上分支),但它仍然是编译的一部分。

或者,如果构建时间不是一个巨大的问题,您可以简单地将两个版本构建到单独的目录中。

自从我做了这样的事情已经有一段时间了,下面应该是你想要的。如果定义了MACRO,则包含该函数,否则,如果该函数是noop,则编译出代码。

 #ifdef MACRO
 #define MACRO_NAME(arg1, arg2, ...) [code to expand to]
 #else
 #define MACRO_NAME(arg1, arg2, ...) noop
 #endif

更新:好吧,我的问题有一点不正确。

大多数静态分析工具可以配置为扫描某些#定义以CPPCheck为例,可以给出以下参数:

-D<ID>               Define preprocessor symbol. Unless --max-configs or
                     --force is used, Cppcheck will only check the given
                     configuration when -D is used.
                     Example: '-DDEBUG=1 -D__cplusplus'.

因此,您可以扫描代码两次,从而实现您的目标。我想说这是两者中最好的,如果你可以添加更多的扫描,如果你添加更多的#define

或者你可以使用下面的一些来扫描更多的配置。

-f, --force          Force checking of all configurations in files. If used
                     together with '--max-configs=', the last option is the
                     one that is effective.

--max-configs=<limit>
                     Maximum number of configurations to check in a file
                     before skipping it. Default is '12'. If used together
                     with '--force', the last option is the one that is
                     effective.

我们在之前的公司使用这种类型的操作,我们为WIN32, Pocket PC, WM5和WM6构建代码,都来自相同的代码库,但对所有构建配置进行静态检查。但是最终的结果是在所有构建中删除了非冗余代码。