c宏扩展,如何生成要在多行中使用的变量名?

时间:2018-04-20 10:17:23

标签: c c-preprocessor

我希望生成唯一的变量名称(我为此使用__LINE__),稍后应在多行中引用该名称。

在特定的一行,比如第17行,我将生成一个名为xyz_17的变量,然后在下面的行中,我可以多次引用xyz_17。但是现在我被困在下面了:

➜  iOS git:(master) ✗ cat macro_expansion_fun.h 
// run `gcc -E macro_expansion_fun.h` to see the expansion
#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)

#define VAR_NAME PASTE(xyz, __LINE__) //at this line I needed a new variable name that is related to the __LINE__ number at this line
int VAR_NAME = 12; //then used in this line and below
VAR_NAME = 13;

➜  iOS git:(master) ✗ gcc -E macro_expansion_fun.h
# 1 "macro_expansion_fun.h"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 331 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "macro_expansion_fun.h" 2





int xyz6 = 12;
xyz7 = 13;

如何在特定行评估VAR_NAME

我实际问题的更多背景知识。它实际上是一个Objective-c应用程序。

#define XLogError(fmt, ...)  do { \
    BUGLY_LOG_MACRO(BuglyLogLevelError, fmt, ##__VA_ARGS__);\
    NSLog(fmt, ##__VA_ARGS__);\
    {\
        NSString *errorString = [NSString stringWithFormat:fmt, ##__VA_ARGS__];\
        if(![errorString containsString:@"Domain Code=-1009 "] && ![errorString containsString:@"Domain Code=-1001 "]){\
            NSAssert(NO, fmt, ##__VA_ARGS__);\
        }\
    }\
} while (0)

我将NSLogBuglyLog(又名第三方崩溃日志服务)和NSAssert包装到宏XLogError中,以便DEBUG } build,我将在我的应用程序中声明所有NSError除少数情况,其中错误表示没有网络连接或超时(基本上不是程序员错误)。

XLogError可能在给定范围内多次使用(见下文)。我想将格式化的错误字符串存储到变量中,以便我可以轻松枚举所有异常情况(数字可能增长,因此将格式化字符串存储到变量中更合理)在if子句中。

用法:

networkCallbackBlock = ^(NSError *error) {
    //some networking error
    FHTLogError(@"restful api error: %@", error);
    NSError *jsonError;
    [NSJSONSerialization dataWithJSONObject:dict options:o error:&jsonError];
    FHTLogError(@"deserialization error: %@", jsonError);
}];

1 个答案:

答案 0 :(得分:2)

__COUNTER__每次在源文件中引用时都会递增,从0开始。所以,加点糖:

static int xyz[];
#define BEGIN_VAR int cur
#define VAR_NAME  xyz[cur]
#define NEW_VAR cur = __COUNTER__; VAR_NAME
#define END_VAR static int xyz[__COUNTER__]

int f( int a ) {
    BEGIN_VAR;
    NEW_VAR = 12;
    VAR_NAME = 13;

    if (a < 0) {
        return VAR_NAME;
    }
    NEW_VAR = 77;
    if (VAR_NAME % a == 0) {
        VAR_NAME++;
    }
    return VAR_NAME;
}

END_VAR;

它不是ISO-C,但是gcc和clang支持它。