有条件的宏扩张

时间:2010-06-13 05:44:11

标签: c objective-c macros conditional

抬头:这是一个奇怪的问题。

我有一些非常有用的宏,我喜欢用来简化一些日志记录。例如,我可以执行Log(@"My message with arguments: %@, %@, %@", @"arg1", @"arg2", @"arg3"),这将扩展为更复杂的方法调用,其中包括self_cmd__FILE____LINE__等内容,等,以便我可以轻松跟踪记录的内容。这很有效。

现在我想扩展我的宏,不仅可以使用Objective-C方法,还可以使用常规的C函数。问题是宏扩展中的self_cmd部分。 C函数中不存在这两个参数。理想情况下,我希望能够在C函数中使用同一组宏,但我遇到了问题。当我使用(例如)我的Log()宏时,我收到关于self_cmd未声明的编译器警告(这完全有道理)。

我的第一个想法是做以下事情(在我的宏中):

if (thisFunctionIsACFunction) {
  DoLogging(nil, nil, format, ##__VA_ARGS__);
} else {
  DoLogging(self, _cmd, format, ##__VA_ARGS__);
}

这仍会产生编译器警告,因为整个if()语句被替换代替宏,导致self_cmd关键字出错(即使它们永远不会执行功能执行)。

我的下一个想法是做这样的事情(在我的宏观中):

if (thisFunctionIsACFunction) {
  #define SELF nil
  #define CMD nil
} else {
  #define SELF self
  #define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);

不幸的是,这不起作用。我在第一个#define上收到“错误:'#'后面没有宏参数”。

我的另一个想法是创建第二组宏,专门用于C函数。这令人厌恶的代码味道,我真的不想这样做。

有什么方法可以在Objective-C方法和C函数中使用同一组宏,如果宏在Objective-C方法中,则只引用self_cmd

修改更多信息:

thisFunctionIsACFunction以一种非常基本的方式确定(我绝对愿意接受改进和建议)。基本上是这样的:

BOOL thisFunctionIsACFunction == (__PRETTY_FUNCTION__[0] != '-' && __PRETTY_FUNCTION__[0] != '+');

它依赖于编译器的行为,为Objective-C对象的实例和类方法添加' - '或'+'。其他任何东西都必须是C函数(因为C函数的名称不能以' - '或'+'开头)。

据我所知,此检查在技术上是运行时检查,因为__PRETTY_FUNCTION__char*取代,这可能是我请求帮助的主要障碍。

3 个答案:

答案 0 :(得分:7)

预处理器在解析实际代码之前完成所有工作。预处理器不能知道函数是C还是obj-C,因为它在解析代码之前运行。

出于同样的原因,

if (thisFunctionIsACFunction) {
  #define SELF nil
  #define CMD nil
} else {
  #define SELF self
  #define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);

无效 - 在编译阶段之前处理#defines。

因此,代码本身必须包含“运行时”检查(尽管编译器可能会对此进行优化)。

我建议定义类似

的内容
void *self = nil; //not sure about the types that
SEL _cmd = nil;   //would be valid for obj-c

在全球范围内; C函数将“看到”这些定义,而Objective-C方法有望用自己的定义隐藏它们。

答案 1 :(得分:1)

您可以使用

if defined "abc" <statement1>
else if defined "def" <statement2>

答案 2 :(得分:0)

您可以使用某种宏条件:

#ifndef OBJECTIVE_C
  #define self 0
  #define _cmd ""
#endif

我不太确定你应该定义什么self_cmd,这些只是猜测。

我不确定是否有预定义的宏可以检查您是否在Objective C中进行编译,因此您可能需要手动定义OBJECTIVE_C作为构建的一部分。