简体   繁体   English

宏值之间的比较在嵌入式编程中是否不好?

[英]Are comparison between macro values bad in embedded programming?

I am building a program that needs to run on an ARM. 我正在构建一个需要在ARM上运行的程序。 The processor has plenty of resources to run the program, so this question is not directly related to this type of processor, but is related to non powerful ones, where resources and computing power are 'limited'. 处理器具有大量的资源来运行程序,因此此问题与这种类型的处理器没有直接关系,但与功能和资源“有限”的功能不强大的处理器有关。

To print debug informations (or even to activate portions of code) I am using a header file where I define macros that I set to true or false, like this: 为了打印调试信息(或什至激活部分代码),我使用了头文件,在其中定义了设置为true或false的宏,如下所示:

#define DEBUG_ADCS_OBC true

and in the main program: 在主程序中:

if (DEBUG_ADCS_OBC == true) {
    printf("O2A ");
    for (j = 0; j < 50; j++) {
        printf("%x ", buffer_obc[jj]);
    }
}

Is this a bad habit? 这是个坏习惯吗? Are there better ways to do this? 有更好的方法可以做到这一点吗?

In addition, will having these IF checks affect performances in a measurable way? 此外,进行这些IF检查是否会以可衡量的方式影响性能?

Or is it safe to assume that when the code is compiled the IFs are somehow removed from the flow, as the comparison is made between two values that cannot change? 还是可以安全地假设,在编译代码时,由于在两个无法更改的值之间进行了比较,因此将IF从流中删除了吗?

Since the expression DEBUG_ADCS_OBC == true can be evaluated at compile time, optimizing compilers will figure out that the branch is either always taken or is always bypassed, and eliminate the condition altogether. 由于表达式DEBUG_ADCS_OBC == true可以在编译时求值,因此优化的编译器将确定分支始终处于执行状态或始终被忽略,并完全消除了这种情况。 Therefore, there is zero runtime cost to the expression when you use an optimized compiler. 因此,使用优化的编译器时,表达式的运行时成本为零。

If you are compiling with all optimization turned off, use conditional compilation instead. 如果在关闭所有优化的情况下进行编译,请改为使用条件编译。 This will do the same thing an optimizing compiler does with a constant expression, but at the preprocessor stage. 这与优化编译器使用常量表达式所做的事情相同,但是在预处理器阶段。 Hence the compiler will not "see" the conditional even with optimization turned off. 因此,即使关闭了优化,编译器也不会“看到”条件。

Note 1: Since DEBUG_ADCS_OBC has a meaning of boolean variable, use DEBUG_ADCS_OBC without == true for a somewhat cleaner look. 注1:因为DEBUG_ADCS_OBC具有布尔变量的含义,所以使用DEBUG_ADCS_OBC不带== true可以使外观更DEBUG_ADCS_OBC

Note 2: Rather than defining the value in the body of your program, consider passing a value on the command line, for example -DDEBUG_ADCS_OBC=true . 注意2:与其在程序主体中定义值,不如考虑在命令行上传递值,例如-DDEBUG_ADCS_OBC=true This lets you change the debug setting without modifying your source code, simply by manipulating the make file or one of its options. 这样,您只需操作make文件或其选项之一,就可以在不修改源代码的情况下更改调试设置。

The code you are using is evaluated everytime when your program reaches this line. 每次程序到达此行时,都会评估您使用的代码。 Since every change of DEBUG_ADCS_OBC will require a recompile of your code, you should use #ifdef/#ifndef expressions instead. 由于DEBUG_ADCS_OBC的每次更改都需要重新编译代码,因此应改用#ifdef /#ifndef表达式。 The advantage of them is, that they are only evaluated once at compile time. 它们的优点是,它们仅在编译时评估一次。

Your code segment could look like the following: 您的代码段可能如下所示:

Header: 标头:

//Remove this line if debugging should be disabled
#define DEBUG_DCS_OBS

Source: 资源:

#ifdef DEBUG_DCS_OBS

printf("O2A ");
for (j = 0; j < 50; j++) {
    printf("%x ", buffer_obc[jj]);
}

#endif

The problem with getting the compiler to do this is the unnecessary run-time test of a constant expression. 使编译器执行此操作的问题是常量表达式的不必要的运行时测试。 An optimising compiler will remove this, but equally it may issue warnings about constant expressions or when the macro is undefined, issue warnings about unreachable code. 一个优化的编译器将删除它,但是同样,它可能会发出有关常量表达式的警告或当宏未定义时发出有关无法访问的代码的警告。

It is not a matter of "bad in embedded programming", it bears little merit in any programming domain. 这不是“嵌入式编程中的坏问题”,在任何编程领域都没有什么好处。

The following is the more usual idiom, will not include unreachable code in the final build and in an appropriately configured a syntax highlighting editor or IDE will generally show you which code sections are active and which are not. 以下是更常见的习惯用法,在最终版本中将不会包含无法访问的代码,并且在经过适当配置的语法突出显示编辑器或IDE中,通常会向您显示哪些代码段处于活动状态,哪些不是。

#define DEBUG_ADCS_OBC

...

#if defined DEBUG_ADCS_OBC
    printf("O2A ");
    for (j = 0; j < 50; j++) 
    {
        printf("%x ", buffer_obc[jj]);
    }
#endif

I'll add one thing that didn't see being mentioned. 我将添加未提及的一件事。

If optimizations are disabled on debug builds, and even if runtime performance impact is insignificant, code is still included. 如果在调试版本上禁用了优化,即使对运行时性能的影响微不足道,仍将包含代码。 As a result debug builds are usually bigger than release builds. 结果,调试版本通常大于发行版本。

If you have very limited memory, you can run into situation where release build fits in the device memory and debug build does not. 如果内存非常有限,则可能会遇到发行版本适合设备内存而调试版本不适合的情况。

For this reason I prefer compile time #if over runtime if . 因此,我更喜欢编译时间#if不是运行时if I can keep the memory usage between debug and release builds closer to each other, and it's easier to keep using the debugger at the end of project. 我可以使调试版本和发布版本之间的内存使用情况更接近,并且在项目结束时更容易使用调试器。

The optimizer will solve the extra resources problem as mentioned in the other replies, but I want to add another point. 优化程序将解决其他答复中提到的额外资源问题,但我想补充一点。 From the code readability point of view this code will be repeated a lot of times, so you can consider creating your specific printing macros. 从代码可读性的角度来看,此代码将重复很多次,因此您可以考虑创建特定的打印宏。 Those macros is what should be enclosed by the debug enable or disable macros. 这些宏应包含在调试启用或禁用宏中。

#ifdef DEBUG_DCS_OBS
myCustomPrint    //your custom printing code
#else
myCustomPrint    //No code here
#end

Also this will decrease the probability of the macro to be forgotten in any file which will cause a real optimization problem. 同样,这将降低宏被遗忘在任何文件中的可能性,这将导致真正的优化问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM