C 预处理器为多种类型赋值

标签 c string macros preprocessor lexer

所以我正在编写一个词法分析器,并且在我的宏生成 token 时遇到了问题( token 是一个具有值类型(枚举)和值( union )的结构。

#define MAKE_TOKEN(token, tokenType, valueType, tokValue) \
    token.type=tokenType; \
    token.value.type=valueType; \
    switch(valueType){ \
        case VAL_NIL: break; \
        case VAL_BOOL: token.value.as.boolean=(bool)tokValue; break; \
        case VAL_NUMBER: token.value.as.number=(double)tokValue; break; \
        case VAL_STRING: token.value.as.string=(char*)tokValue; break; \
    }
例如,如果 tokValue 为 5(因为 5 可以转换为 bool、double 和 char*),则此方法有效,但是,这不会编译,因为编译器无法将字符串转换为 double。这意味着当值类型为 VAL_STRING 时无法使用该宏,如何解决这个问题?

最佳答案

你不能让它作为宏工作,因为 C 预处理器中的宏仅执行字符串插值,因此麻烦的行会执行以下操作:

    case VAL_NUMBER: token.value.as.number=(double)"some_string"; break;

只需使用一个函数即可。没有明显的理由使该片段成为宏。

void MAKE_TOKEN(struct token *token, enum token_type tokenType, enum value_type valueType, void *tokValue) {
    token->type = tokenType;
    token->value.type = valueType; 
    switch(valueType){
    case VAL_NIL:
        break;
    case VAL_BOOL:
        token->value.as.boolean = *(bool*)tokValue;
        break;
    case VAL_NUMBER:
        token->value.as.number = *(double*)tokValue;
        break;

    case VAL_STRING:
        token->value.as.string = *(char**)tokValue;
        break;
    }
}

关于C 预处理器为多种类型赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002201/

相关文章:

c - 为什么默认编译器标志未显示在 gcc 行中?

c - “noreturn”函数确实返回

javascript - 删除 URL 开头的字符串

C测试变量是否在只读部分

c++ - 如何实现这样的c++宏

ios - 目标 Interface Builder 的预处理器宏不适用于 OS X?

c++ - 图中边的顶点之间的最短路径不应是边本身

java - C 到 Java 的转换

c - 返回指向子数组的指针

java - Hashtable<String, Object> 找不到字符串