C 预处理器宏替换#if#else 语句

标签 c gcc macros c-preprocessor avr

我现在正在使用此语句在我的 C 代码中的小错误消息和更广泛的错误消息之间切换:

#ifdef COMPACTC
  error_code ((uint16_t) init_cascade, 5);
#else
  error_message (__func__, "cascades malloc failed");
#endif

(它是嵌入式 C 代码库的一部分,所以我经常没有足够的内存来存储错误消息字符串)。

在第一种情况下(COMPACTC 定义)我只输出一个函数地址和错误号。在第二种情况下,我输出了完整的函数名称和一条人类可读的错误消息。

由于我现在在整个代码中都复制了这个片段,我希望我可以用一个宏替换它,我可以像这样使用它:

error (init_cascade, "cascades malloc failed", 5)

并根据是否定义了 COMPACTC 提供正确的 C 代码。

也许甚至可以从当前位置自动派生当前函数(或某些唯一标识符),尽管我认为预处理器不知道它当前在哪个函数的范围内。

另一个改进是,如果一个唯一的错误代码(在本例中为 5,它基于返回值)可以从错误消息(如哈希值或其他东西)中自动生成。

那么宏调用就可以这么简单:

error ("cascades malloc failed")

当然,在使用哈希时,我需要对其原始消息的某种引用(文件/评论)。

上下文:AVR 8 位 MCU 上的错误消息

关于这个问题的上下文:此代码是为 ATmega168(只有 2k RAM)编写的,据我所知,Linux 没有可用的/最新的模拟器。因此,我试图找到一种生成错误消息/代码的好方法,而不会让字符串占用我所有的内存。

替代方案:C 函数?

一个完全不同的,可能更灵活的解决方案是定义一个 C 函数 error (function, message, code) 并移动 #if/#else/#endif 构建它的 body 。 我不确定如果字符串文字在函数调用中被引用但从未在函数体内使用过,它是否由 gcc 编译。

编辑:我刚刚测试了这个想法:在调用中使用字符串文字但不在正文中使用它仍然通过 gcc 添加到可执行文件中,所以这个“替代方案”似乎不起作用。

最佳答案

这实际上应该相当简单:

#ifdef COMPACTC
#   define COMBINED_ERROR(function, message, size) error_code((uint16_t)function, size)
#else
#   define COMBINED_ERROR(function, message, size) error_message (__func__, message)
#endif

现在你可以写:

COMBINED_ERROR(init_cascade, "cascades malloc failed", 5);

关于C 预处理器宏替换#if#else 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36250822/

相关文章:

windows - 如何编译mingw-w64-crt

c - 学习C语言宏的建议

c++ - GCC:如何访问基本类型定义?

macros - 在 OpenOffice Calc 中自动化图表标题

c++ - GCC:__attribute__ ((format (printf, x, y)) 在使用可变参数宏调用函数时似乎不起作用

c - C中生产者-消费者的线程安全环形缓冲区

c# - 在 C# 中使用 C++ DLL

c - ifndef 是否总是在用空替换列表定义的类对象宏上工作

c - 使用 Shell 脚本将数据发送到正在运行的进程

c - 奇怪的不兼容的指针分配