首页 > 代码库 > Too many arguments provided to function-like macro invocation 或
Too many arguments provided to function-like macro invocation 或
1、问题
2、解决问题的办法
将Build Setting下的Apple LLVM 7.0选择成GUN99
3、产生此问题的原因
3.1、在NSException.h的文件中定义了如下宏
/* * Asserts to use in Objective-C method bodies */#if !defined(NSAssert)//使用了NSAssert宏#define NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5)) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#define NSAssert4(condition, desc, arg1, arg2, arg3, arg4) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), 0) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#define NSAssert3(condition, desc, arg1, arg2, arg3) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), 0, 0) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#define NSAssert2(condition, desc, arg1, arg2) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), (arg1), (arg2), 0, 0, 0) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#define NSAssert1(condition, desc, arg1) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), (arg1), 0, 0, 0, 0) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#define NSAssert(condition, desc) __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS _NSAssertBody((condition), (desc), 0, 0, 0, 0, 0) __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS#endif
//在如下NSAssert的定义中,出现了##__VA_ARGS__#define NSAssert(condition, desc, ...) do { __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS if (!(condition)) { NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; __assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>"; [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:__assert_file__ lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; } __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS } while(0)#endif
3.2 ##__ VA_ARGS__的追本溯源
1)##__ VA_ARGS__代表带有可变参数的宏
2)可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。
即Xcode的Build Setting下的Apple LLVM 7.0要选择成GUN99。
3)在1999年版本的ISO C 标准中,宏可以象函数一样,定义时可以带有可变参数。宏的语法和函数的语法类似。下面有个例子:
//’…’指可变参数,被表示成零个或多个符号,包括里面的逗号.//当被调用时,在宏体(macro body)中,那些符号序列集合将代替里面的__VA_ARGS__标识符。#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
4)GCC始终支持复杂的宏,它使用一种不同的语法从而可以使你可以给可变参数一个名字,如同其它参数一样。例如下面的例子:
#define debug(format, args...) fprintf (stderr, format, args)
5)CPP使用一个特殊的’##’操作。书写格式为:
//这里,如果可变参数被忽略或为空,’##’操作将使预处理器(preprocessor)去除掉它前面的那个逗号。//如果你在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。像其它的pasted macro参数一样,注意这些参数不是宏的扩展。#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
C/C++可变参数,“## __VA_ARGS__”宏的介绍和使用 » reille blog
— 今天阅读代码的时候,在一个宏定义语句中,发现了个之前未曾见过的编译器预定义宏:“__VA_ARGS__”。当时,从代码语句中推测它代表宏参数:“…”(本文称之为省略号),依稀记得printf函数声明中有使用这个省略号,大概的意思是表示可变化的参数,但未深入了解。
Too many arguments provided to function-like macro invocation 或
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。