【问题标题】:How can I check if there is an assignment in a macro's parameter?如何检查宏的参数中是否有赋值?
【发布时间】:2015-05-16 08:27:26
【问题描述】:

我们如何检查宏参数中是否有赋值,如下例所示?

定义:

#define value(x) {...}

呼叫:

case a: value( a = 10 )
case b: value( 10 )

我想要做的是通过以下方式实现一个字符串枚举:

#define STR_ENUM_DICT_ITEM_(value)  [@((MethodX value)) stringValue]:@#value,
#define STR_ENUM_DICT_ITEM(idx, value)  STR_ENUM_DICT_ITEM_(value)         

#define STR_ENUM(type, name, ...) \
typedef NS_ENUM (type, name){__VA_ARGS__}; \
NSString *name##_S(type value) \
{ \
    static NSDictionary   *values; \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        values = @{ \
            metamacro_foreach(STR_ENUM_DICT_ITEM, , __VA_ARGS__) \
        }; \
    }); \
    return [values valueForKey:[@(value)stringValue]]; \
}  

STR_ENUM(NSUInteger, MethodX,
   Method1 = 100// this is comment
   , Method2
   , Method3 = Method1
);

所以我需要检查参数中是否有赋值,或者其他方式 可以得到(Method1 = 100)或者(Method3 = Method1)的值,结果是100, 100。

【问题讨论】:

  • 由于预处理器只做简单的文本替换,你不能做太多检查扩展参数。
  • 吹毛求疵:没有叫马科斯。
  • 大概你的意思是在编译时检查,而不是在运行时检查?
  • 为什么是enums 标签,顺便说一句?
  • 为什么人们更喜欢宏?编译器更好,因为它有更多信息

标签: c++ c string enums macros


【解决方案1】:

在性能方面不是很有效,但它确实有效:

#define value(x) \
  do { \
    assert(!strchr(#x, '=')); \
    /* rest of macro */ \
  } while (0)

这是一个简单的示例,仅涵盖 OP 提供的两种情况。但是,使用# 运算符将宏的参数转换为“字符串”,可以创建复杂的规则来进行测试。

【讨论】:

  • 取决于作者想要value(a==10) 甚至value('=') 的行为。
  • 顺便说一句,我认为您可以将其转换为编译时检查,因为 #x 在编译时是已知的,因此性能没有问题
  • @Wangchao,我问过你的两个问题——这是什么语言? C++ 中有一个编译时解决方案。这是 Objective-C++ 还是 Objective-C?你已经用 c 和 c++ 标签标记了这个问题,但很少有人真正使用 Objective-C++。
  • 对不起,我刚看到消息。这只是一个 c/c++ 问题。
【解决方案2】:

您能否详细说明您想区分哪些情况?怎么样

value(a)
value(a+2)
value(a==10)
value(a<=10)
value('=')

?

如果它包含分配,您希望发生什么?编译错误还是其他什么?

由于编译错误,我设法得到了以下工作

#define check(a) if (a==a);

int main() {
   int a;
   check(10);
   check(a);
   check(a+2);
   check(a==10);
   check(a<=10);
   check('=');
   check(a=10);
   return 0;
}

除了a=10 之外的每个宏都可以编译。后者变成a=10==a=10,无法编译。

【讨论】:

    猜你喜欢
    • 2013-10-15
    • 2021-12-08
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多