Android-NDK-需要1+args的可变宏

Android - NDK - Variadic macro requiring 1+ args

本文关键字:需要 1+args Android-NDK-      更新时间:2023-10-16

我的日志库中有以下宏:

#define TRACE_E(__logCat,__format,...) 
    do { 
        ::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); 
        if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) 
        { 
            __catPtrVal->Error( __format, __VA_ARGS__ ); 
        } 
    } while( false )

在Visual Studio(2008)下,它可以按预期工作,即我可以同时执行TRACE_E( pLog, "some message without parameters" );TRACE_E( pLog, "some message with parameters %d %d", 4, 8 );

但是,当我在eclipse和Android NDK中使用同一个库时,如果我不在宏中的格式字符串后面传递至少一个参数,就会出现编译错误,即TRACE_E( pLog, "some message without parameters" );无效,但TRACE_E( pLog, "some message without parameters", 0 );有效,这迫使我在不需要任何参数的情况下传递一个伪参数。

当使用g++而不是Visual Studio的编译器时,可变宏的行为有什么不同吗?非常感谢。

是。您正在尝试的内容在标准C或C++中是不可能的。

这可以说是各自标准中的一个缺陷,不同的编译器有不同的解决方案。Visual Studio试图使其按原样工作,gcc和clang需要以下语法:

__catPtrVal->Error( __format, ##__VA_ARGS__ );

这里对gcc进行了描述;clang只是采用了gcc的做事方式。不幸的是,MSVC不理解这种语法。据我所知,在一般情况下,没有可移植的方法来解决这个问题。

不过,对于您的特定宏,您可以简单地编写

#define TRACE_E(__logCat,...) 
    do { 
        ::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); 
        if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) 
        { 
            __catPtrVal->Error(__VA_ARGS__ ); 
        } 
    } while( false )

因为您使用__format的唯一位置直接位于__VA_ARGS__之前。

旁注:你在那里使用了很多保留的标识符。除非您正在编写一个标准的库实现,否则您应该更容易使用下划线。