【问题标题】:How should I pass NULL to the va_list function parameter?我应该如何将 NULL 传递给 va_list 函数参数?
【发布时间】:2013-03-10 11:01:57
【问题描述】:

我想将 NULL 传递给以下函数的第四个参数:

bool CCMenuItemToggle::initWithTarget(CCObject* target, SEL_MenuHandler selector, CCMenuItem* item, **va_list args**);

像这样:

CCMenuItemToggle::initWithTarget(this, menu_selector(GOSound::toggleButtonCallback), NULL, NULL);

当我在 XCode (clang3.1) 中构建它时没问题。但是当我将代码移植到android ndk(g++4.7)时,编译失败:

没有从“int”到“va_list”(又名“__builtin_va_list”)的可行转换

我应该如何处理?

【问题讨论】:

    标签: c++ android-ndk g++ variadic-functions


    【解决方案1】:

    如果您只使用空的 va_list 而不是 NULL,我假设您的代码将起作用。

    CCMenuItemToggle::initWithTarget( this, menu_selector(GOSound::toggleButtonCallback)
                                    , NULL, va_list() );
    

    编辑: 也许这个替代解决方案适用于两种编译器。

    va_list empty_va_list = va_list();
    CCMenuItemToggle::initWithTarget( this, menu_selector(GOSound::toggleButtonCallback)
                                    , NULL, empty_va_list );
    

    【讨论】:

    • 我只是注意到我使用 ndk(clang3.1) 测试了您的解决方案。当我切换回ndk(g++4.7)时,报错:internal compiler error: in build_zero_init_1, at cp/init.c:280
    • 好吧,我不认为我对此负责。答案仍然是正确的。编译器坏了。也许它有助于在调用之前声明一个变量并传递变量。请参阅上面的编辑。
    • 由于传递了一个未初始化的变量,这可能是技术上未定义的行为?
    • @M.M 我添加了一个初始化。
    • GCC 6.2 中的第二个 sn-p:错误:“va_list”之前的预期表达式。
    【解决方案2】:

    我看到这个问题得到了回答,但它不是标准的。以下代码将通过 Visual Studios 中的运行时错误;但是,它适用于 g++。

        va_list empty_va_list;
    CCMenuItemToggle::initWithTarget( this, menu_selector(GOSound::toggleButtonCallback), NULL, empty_va_list );
    

    更好的解决方案是创建几个帮助函数来构造一个空的 va_list。

    va_list CCMenuItemToggle::createEmptyVa_list()
    {
       return doCreateEmptyVa_list(0);
    }
    
    va_list CCMenuItemToggle::doCreateEmptyVa_list(int i,...)
    {
        va_list vl;
        va_start(vl,i);
        return vl;
    }
    

    将 doCreateEmptyVa_list 设为私有,然后在调用函数时调用

    CCMenuItemToggle::initWithTarget( this, menu_selector(GOSound::toggleButtonCallback), NULL, CreateEmptyVa_list() );
    

    【讨论】:

    • 这看起来很可疑; vl 在某种意义上是“悬空的”。
    • “在使用 va_start 初始化 va_list 对象的函数返回之前,应调用 va_end 宏。” cplusplus.com/reference/cstdarg/va_list
    【解决方案3】:

    您不能将NULL 作为函数的第四个参数传递。该函数需要 va_list 参数。 NULL 在一般情况下不是 va_list 对象的有效初始化程序。所以,你的问题的答案是:不可能。

    你应该如何处理它取决于你想要做什么。

    【讨论】:

    • “你想要做什么”这里是:调用函数。其他参数的值决定了函数永远不会使用va_list 参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 2020-05-13
    相关资源
    最近更新 更多