• 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__)
  • 相关阅读:
    DcotrineFixtureBundle学习
    php方法(1)
    学习笔记(2)
    微信access_token的获取
    学习笔记(1)
    与你相遇——博客园
    单例模式
    Java集合
    sql 优化
    缓存与数据库的数据一致性的解决方案(转)
  • 原文地址:https://www.cnblogs.com/liaolijun/p/5829516.html
Copyright © 2020-2023  润新知