如何从一个C宏的值一个字符的字符串? [英] How to make a char string from a C macro's value?

查看:156
本文介绍了如何从一个C宏的值一个字符的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,如何避免写'func_name的两次?

 的#ifndef TEST_FUN
#定义TEST_FUN FUNC_NAME
#定义TEST_FUN_NAMEFUNC_NAME
#万一

我想跟着单点真相的规则。

çpreprocessor的版本:

  $ CPP --version
CPP(GCC)4.1.2 20070626(红帽4.1.2-14)


解决方案

他谁是害羞 * 给你一个答案的胚芽,但只有胚芽。转换一个值在C pre处理器字符串的基本技术的确是通过'#'操作,但提出的解决方案的简单音译得到一个编译错误:

 的#define TEST_FUNC test_func
#定义TEST_FUNC_NAME #TEST_FUNC#包括LT&;&stdio.h中GT;
INT主要(无效)
{
    看跌期权(TEST_FUNC_NAME);
    返回(0);
}

语法错误是在看跌期权()'行 - 问题是在源'流浪#'

在C标准,'#操作符的部分6.10.3.2,它说:


  

在各#preprocessing令牌
  对于函数样的替换列表
  宏应该紧跟一个参数
  作为下一个preprocessing令牌
  替换列表。


麻烦的是,你可以宏参数转换为字符串 - 但你不能转换不属于宏观参数随机项目

那么,要实现你后的效果,你肯定必须做一些额外的工作。

 的#define FUNCTION_NAME(名称)#NAME
#定义TEST_FUNC_NAME FUNCTION_NAME(test_func)#包括LT&;&stdio.h中GT;INT主要(无效)
{
    看跌期权(TEST_FUNC_NAME);
    返回(0);
}

我不是你打算如何使用宏完全清楚,你打算怎样完全避免重复。这个稍微复杂的例子可能更丰富。使用宏相当于STR_VALUE是一个成语是必要的,以获得所需的结果。

 的#define STR_VALUE(AR​​G)#arg
#定义FUNCTION_NAME(名)STR_VALUE(名)#定义TEST_FUNC test_func
#定义TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)#包括LT&;&stdio.h中GT;静态无效TEST_FUNC(无效)
{
    的printf(在函数%S \\ n,TEST_FUNC_NAME);
}INT主要(无效)
{
    看跌期权(TEST_FUNC_NAME);
    TEST_FUNC();
    返回(0);
}


*在最初的时候写这个答案的时候,用名字' shoosh 害羞为名称的一部分。

For example, how to avoid writing the 'func_name' twice?

#ifndef TEST_FUN
#  define TEST_FUN func_name
#  define TEST_FUN_NAME "func_name"
#endif

I'd like to follow the Single Point of Truth rule.

Version of C preprocessor:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)

解决方案

He who is Shy* gave you the germ of an answer, but only the germ. The basic technique for converting a value into a string in the C pre-processor is indeed via the '#' operator, but a simple transliteration of the proposed solution gets a compilation error:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

#include <stdio.h>
int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

The syntax error is on the 'puts()' line - the problem is a 'stray #' in the source.

In section 6.10.3.2 of the C standard, 'The # operator', it says:

Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.

The trouble is that you can convert macro arguments to strings -- but you can't convert random items that are not macro arguments.

So, to achieve the effect you are after, you most certainly have to do some extra work.

#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME  FUNCTION_NAME(test_func)

#include <stdio.h>

int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

I'm not completely clear on how you plan to use the macros, and how you plan to avoid repetition altogether. This slightly more elaborate example might be more informative. The use of a macro equivalent to STR_VALUE is an idiom that is necessary to get the desired result.

#define STR_VALUE(arg)      #arg
#define FUNCTION_NAME(name) STR_VALUE(name)

#define TEST_FUNC      test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)

#include <stdio.h>

static void TEST_FUNC(void)
{
    printf("In function %s\n", TEST_FUNC_NAME);
}

int main(void)
{
    puts(TEST_FUNC_NAME);
    TEST_FUNC();
    return(0);
}


* At the time when this answer was first written, shoosh's name used 'Shy' as part of the name.

这篇关于如何从一个C宏的值一个字符的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆