Too many arguments provided to function-like macro invocation

 接入SDK时移植代码发现报错了。

Too many arguments provided to function-like macro invocation
Parentheses are required around macro argument containing braced initializer list

 代码如下:

 

IEagle_setRespCallback(^(BOOL isSuccess, id object) {
        if (isSuccess) {
            NSLog(@"Demo:%@", @"二次验证(登录验证)回调成功");
            /** 收到二次验证回调成功后 方可进入游戏 */
            
            testCount = testCount + 1;
            
            NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"2", nil];
        } else {
            NSLog(@"Demo:%@",@"二次验证(登录验证)回调失败");
        }
    });

这个NSDictionary 初始化的代码应该没什么问题的,但是在Block里面缺报错了。奇怪了。

 方法一:事实上Xcode自带提示了Fix功能,点击Fix后问题解决了

 

IEagle_setRespCallback((^(BOOL isSuccess, id object) {
        if (isSuccess) {
            NSLog(@"Demo:%@", @"二次验证(登录验证)回调成功");
            /** 收到二次验证回调成功后 方可进入游戏 */
            
            testCount = testCount + 1;
            
            NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"1", @"2", nil];
        } else {
            NSLog(@"Demo:%@",@"二次验证(登录验证)回调失败");
        }
    }));

其实Xcode给出的解决办法就是在匿名Block之间加了对括号。

 报错的翻译为:

为类似宏调用的函数提供的参数太多

包含大括号初始值设定项列表的宏参数周围需要括号

方法二: 就是不要用匿名Block

 

void(^loginCallback)(BOOL, id) = ^(BOOL isSuccess, id object) {
        if (isSuccess)
        {
            NSLog(@"Demo:登录成功");


            NSDictionary *dic1 =[NSDictionary dictionaryWithObjectsAndKeys:gameId,@"sdk_gameId",
                                channelId,@"sdk_channelId" ,
                                appId,@"sdk_appId" ,
                                sessionId,@"sdk_sid" ,
                                extra, @"sdk_extra",
                                nil];

            [stifle_gas sendU3dMessage:@"LoginSdkCallBack" param:dic1 resultString:nil];

        }
        else
        {
            NSLog(@"Demo:登录失败[%@]", (NSString *)object);
        }
    };
    
    // 登录回调
    IEagle_setLoginCallback(loginCallback);

方法三:在编译有问题的地方直接加括号,当然这样写代码不太方便

// 二次验证回调
    IEagle_setRespCallback(^(BOOL isSuccess) {
        if (isSuccess) {
            NSLog(@"Demo:%@", @"二次验证(登录验证)回调成功");
            /** 收到二次验证回调成功后 方可进入游戏 */
            
            ([NSString stringWithFormat:@"%@", @"test"]);//这里加一对括号就能编译通过了
        } else {
            NSLog(@"Demo:%@",@"二次验证(登录验证)回调失败");
        }
    });

 原理分析

 找了很久都只有一篇有用的文章http://www.it1352.com/470834.html

int val1 = 0;
int val2 = 1;

const auto check = [val1,val2]()-> bool
{
    return val1 < val2;
};
// no error for this call
assert(check() && "Test is failed");

// no error for this call
assert([=]()-> bool
       {
           return val1 < val2;
       }() && "Test is failed");
//compile error for this call "too many arguments provided to function-like macro invocation"
assert([val1,val2]()-> bool
       {
           return val1 < val2;
       }() && "Test is failed");

The problem is the comma in the capture list.

The preprocessor has an extremely limited understanding of the C++ syntax, it mainly does trivial text substitution. If a comma is not between matching inner parenthesis (and not part of a token like a string literal of course), the preprocessor will treat it as a separator of arguments of the macro invocation.

So the preprocessor thinks you are invoking assert with the two arguments [this and the rest of the stuff behind the first comma, which yields the error.

You can fix this error by using an extra set of parenthesis:

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives,155 the behavior is undefined.

翻译后的关键文字如下:

 编译错误当我使用assert宏并在捕获列表中使用多个参数定义lambda(匿名函数)时会出现这种情况

问题是逗号在捕获列表中。

 

预处理器对C ++语法的理解非常有限,它主要是简单的文本替换。如果逗号不在匹配的内括号之间(而不是像字符串文字一样的令牌的一部分),预处理器将它作为宏调用的参数的分隔符。

 

因此,预处理器认为你使用两个参数 [this ]和第一个逗号后面的其他东西调用assert,产生错误。

 

您可以使用一组额外的括号来修复此错误:

  int i = -7,j = 7; 
 assert(([i,j](){return i + j;}())); 

 总结:

宏定义函数IEagle_setRespCallback调用了捕获列表中使用多个参数定义lambda(匿名函数)^(BOOL isSuccess, id object) { , ,}时,预处理器对C ++语法的理解非常有限,它主要是简单的文本替换。如果逗号不在匹配的内括号之间(而不是像字符串文字一样的令牌的一部分),预处理器将它作为宏调用的参数的分隔符。

宏定义函数 + lambda(匿名函数)逗号,这时要多加一对括号来区分匿名函数的参数和宏定义的参数。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: "too many arguments to function"错误通常发生在函数调用时传递了太多的参数。这可能是因为函数的定义和函数的调用之间的参数数量不匹配。在引用\[1\]中的代码中,函数func1的定义是void func1(void),它没有参数,但在main函数中调用func1时传递了一个参数&p。这导致了"too many arguments to function"错误的发生。要解决这个问题,可以修改函数的定义,使其接受一个参数,或者在函数调用时删除多余的参数。 #### 引用[.reference_title] - *1* [[Error] too many arguments to function 'func1'(DEV编辑器)](https://blog.csdn.net/weixin_45375831/article/details/96473417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [编译错误“Too many arguments to function call....”](https://blog.csdn.net/potato512/article/details/44489537)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [objc_msgsend 报错 Too many arguments to function call](https://blog.csdn.net/lnking1992/article/details/127286321)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值