如何用C中#define宏中的字符串常量替换函数名

Posted

技术标签:

【中文标题】如何用C中#define宏中的字符串常量替换函数名【英文标题】:How to replace function name with string constant in #define macro in C 【发布时间】:2014-07-15 12:21:21 【问题描述】:

我希望使用预处理器指令将函数调用替换为字符串。 像这样的:

#ifdef DEBUG
    #define Func1(arg) "Function not supported"
#endif

所以基本上当有人调用这个函数时,我想要一个编译错误,这样这个函数在DEBUG 模式下是不可见的,代替那个,在编译日志中打印以下字符串。 此方法会引发错误。 当func1() 被调用时,还有其他方法可以打印我想要的特定字符串吗?

【问题讨论】:

请澄清“引发错误”。是编译错误吗?运行时错误?在使用站点提供错误描述和代码。 确切的错误是:“错误:表达式必须具有(指向)函数类型”...。此错误在调用此函数的位置引发。 信息有那么重要吗? 【参考方案1】:

归档这种行为最明显的方法是使用#error 指令。但是,由于不可能构造“有条件的#error 指令”,我猜下一步是在 C99 中引入的_Pragma 运算符。这是在编译期间产生消息的解决方案:

#include <stdio.h>

#define DEBUG 1

#ifdef DEBUG
    #define Func1(arg) _Pragma("message \"Function not supported.\"")
#endif

void (Func1)(int arg)



int main(void)

    Func1(1);
    Func1(2);
    Func1(3);

    return 0;

编译(与gcc):

...
check.c:15: note: #pragma message: Function not supported.
check.c:16: note: #pragma message: Function not supported.
check.c:17: note: #pragma message: Function not supported.

我知道这不是直接的解决方案(这样的消息甚至不被视为警告,所以-Werror 不会改变任何东西),但是你可以使用例如grep 工具或任何其他方法来扫描编译器的输出。

从 GCC 4.8 开始,还有 #pragma GCC error "message",这是直接(但不可移植)的解决方案。查看this answer 了解更多信息。例如:

#ifdef DEBUG
    #define Func1(arg) _Pragma("GCC error \"Function not supported.\"")
#endif

【讨论】:

我的问题是,我需要在调用函数的地方出现编译错误。在您的解决方案中,将在实际编译函数之前处理预处理器。所以当以顺序方式处理时,预处理器不会执行。 @user3840787:“执行”Func1(arg) 类函数宏的实际位置是main 定义中的Func1(1); 指令。定义宏并不重要,如果没有适当的调用,它不会做任何事情。【参考方案2】:

一种方法是简单地保留函数未定义。这将导致链接时出错。

如果你使用 gcc,你可以使用它的一个扩展,一个函数属性:

#ifndef DEBUG
#define __nodebugonly
#else
#define __nodebugonly __attribute__((error("Function not supported")))
#endif

void Func1(int arg) __nodebugonly;

【讨论】:

对,我在这方面误读了你的问题。因为__debugonly 用词不当,所以我也改了。【参考方案3】:

你可以使用

#error "Function not supported"

中止编译。 但是很明显,当有人可以访问可以删除的源时 - 那么你到底想做什么呢?

如果您不信任这些人提供您的资源,请不要将其提供给他们。 将其链接到 .obj 中,用 .h 定义“接口”,然后只给出它。

【讨论】:

我本可以使用#error... :) 但是在处理预处理器时会立即调用它,而不是在调用函数时。 :( :(

以上是关于如何用C中#define宏中的字符串常量替换函数名的主要内容,如果未能解决你的问题,请参考以下文章

c语言定义常量define

可以使用命令define定义变量吗

怎么把C语言中定义的符号变量替换为对应的常量?求代码

C语言中如何用一个字符串替换一个主串中的子串

C语言学习笔记--C语言中的宏定义

如何用函数链中的空字符串替换数据库中的空值