Xcode开发,我可以放置#pragma未使用(x)通过一些#define规则



在Xcode中开发时,通常会在Debug之间切换。和模式,只在调试模式下使用部分代码,而在发布模式下不使用部分代码。

我经常通过一些#define规则抛出NSLog代码,这些规则允许预编译器解析出发布中不需要的那些命令。这样做是因为一些最终的测试需要证明一切都像预期的那样工作,错误仍然被正确处理,而不会干扰一些我可能忘记的NSLog。这在音频开发中是一个重要的例子,在音频开发中,日志记录通常是相对高效的,但在调试时是需要的。将所有内容包装在#ifdef DEBUG中有点麻烦,并且使代码锁定疯狂,因此我的#定义工作得很好,以保持代码简单易读,而无需担心发行版中留下的NSLog,同时如果需要的话仍然有意登录。这种做法对我来说非常有效,可以使用纯发布代码进行适当的测试场景。

但是这会导致编译器警告一些变量根本没有被使用。这不是什么大问题,但我想更进一步,试着消除这些警告。现在我可以在Xcode中关闭这些警告但是我试图找到一种方法来保留这些警告并消除它们对于我的NSLog被否决的#define

所以,而不是记录对dev>null我抛出(无效)所有的代码是由NSLog(包装…)和使用一些额外定义的规则ALLWAYSLog(),故意将NSLog保留在发布中,并将NSLog更改为fprintf以避免应用程序起源和时间打印。这是我的规则…

#ifdef DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr, "%s n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])
#else
#define NSLog(FORMAT, ...) {;}
#endif
#define ALLWAYSLog(FORMAT, ...) fprintf(stderr, "%s n", [[[NSString alloc] initWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])

为了消除那些未使用的变量警告,我们经常使用

#pragma unused(variablename)

告知预编译器我们是故意这样做的

问题:
是否可以编写一些利用#pragma unused(x)#define规则
或者如何集成__unused属性的上述方式

#else的情况下,您可以将函数调用放在&&操作符的右侧,左侧为0。这将确保变量被"使用"。同时确保函数实际上不会被调用,参数也不会被求值。

#ifdef DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr, "%s n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])
#else
#define NSLog(FORMAT, ...) (0 && fprintf(stderr, "%s n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]))
#endif

经过测试仍然不相信没有"官方方法";这样做,我结束了再次阅读我的头文件。(usr/include/sys/cdefs.h)

__unused声明为__attribute__((__unused__))

这似乎是通过在代码的正确位置放置__unused指令来告诉Apple Clang (GCC)编译器不有意使用特定变量的官方方式。例如,在变量声明的前面或函数声明之后等等。参见stackoverflow讨论开始2013正在进行

@dbush的答案很好,因为它通过使用传递的参数和引入不会造成伤害的null逻辑来抑制未使用的变量警告,但仍然会执行以查找"表达式结果未使用"。这是非常接近我的目标,可能仍然是最简单的解决方案。

在例子:

#define NSLog(...) (0 && fprintf(stderr,"%s",[[NSString alloc] initWithFormat:__VA_ARGS__].UTF8String))
// applied to
int check = 333;
NSLog(@"findMeAgainInPreProcess %d",check);
// preprocesses to
int check = 333;
{0 && fprintf(__stderrp,"%s n",[[NSString alloc] initWithFormat:@"findMeAgainInPreProcess %d",check].UTF8String);};

虽然这不会打印任何内容,但编译器知道该表达式是未使用的。

但是这给我留下了一个问题,未使用的标记是如何正确完成的。尝试一种互惠的方法来区分调试和发布,再次使用__unused与我的第一种方法相结合,像这样…

#define ALLWAYSLog(...) fprintf(stderr,"%s n",[[NSString alloc] initWithFormat:__VA_ARGS__].UTF8String)
#ifdef DEBUG
#define IN_RELEASE__unused
#define NSLog(...) ALLWAYSLog(__VA_ARGS__)
#else
#define IN_RELEASE__unused __unused
//#define NSLog(...) (0&&ALLWAYSLog(__VA_ARGS__)) //@dbush solution
//#define NSLog(...) NSCAssert(__VA_ARGS__,"")
//#define NSLog(...) {;}
#define NSLog(...) /*__VA_ARGS__*/
#endif

在调试中,它不会通过解析指令本身来沉默未使用的变量警告,在发布中,它会根据宏将IN_RELEASE__unused交换为__unused并沉默它。这是一点额外的工作,但可以帮助查看哪些部分是故意未使用的。

表示我可以在下面输入…

IN_RELEASE__unused int check = 333;
NSLog(@"findMeAgainInPreProcess %d",check);
// produces for DEBUG
int check = 333; //no warning, var is used below
fprintf(__stderrp,"%s n",[[NSString alloc] initWithFormat:@"findMeAgainInPreCompile %d", check].UTF8String);
// produces for RELEASE
__attribute__((__unused__)) int check = 333; //no warning intentionally
; // no print, nothing

这使NSLog保持在适当的位置(在代码中),标记未使用的变量以适当地沉默警告,并且NSLog在发布中被完全解析出来。我仍然可以使用引入的allwaylog强制打印两种模式。

结论:dbush的解决方案更直接。

相关内容

  • 没有找到相关文章

最新更新