#define va_arg(list,mode) ( (mode *) ( list += sizeof(mode) ) [-1]
不知道[-1]怎么看?指针能不能指向这个位置?我认为这指向mode中的前一个值
[-1]
b09cbbtk1#
#define va_arg(list,mode) ( (mode *) ( list += sizeof(mode) ) [-1]这是va_arg宏的一个实现,将由<stdarg.h>为C 2018 7.16中的C变量参数特性定义。当使用这个宏时,list应该是va_list对象,而mode应该是型别。在这个C实作中,va_list显然是实作为字符型别的指标,或是在扩充指标算术以使用void *的C实作中,实作为void的指标。然后list += sizeof(mode)将list向前推进mode类型对象中的字节数,以考虑即将被宏“消耗”的参数。然后( list += sizeof(mode) )之前的(mode *)转换将指针转换为指向所需类型。但是,由于+=,它现在指向所需参数之后。而这个指针值是+=表达式和强制转换的结果。因此,它后面的[-1]用于提取list指向的位置之前的元素。我怀疑使用[-1]的这种略微笨拙的构造是为了避免在宏中两次使用list,这是避免多次计算副作用的好做法,以防宏参数是一个具有副作用的表达式。请注意,在list += sizeof(mode)中使用list可能是一个错误或疏忽;它应该是(list) += sizeof(mode)。
va_arg
<stdarg.h>
list
va_list
mode
void *
void
list += sizeof(mode)
( list += sizeof(mode) )
(mode *)
+=
(list) += sizeof(mode)
1条答案
按热度按时间b09cbbtk1#
#define va_arg(list,mode) ( (mode *) ( list += sizeof(mode) ) [-1]
这是
va_arg
宏的一个实现,将由<stdarg.h>
为C 2018 7.16中的C变量参数特性定义。当使用这个宏时,
list
应该是va_list
对象,而mode
应该是型别。在这个C实作中,va_list
显然是实作为字符型别的指标,或是在扩充指标算术以使用void *
的C实作中,实作为void
的指标。然后
list += sizeof(mode)
将list
向前推进mode
类型对象中的字节数,以考虑即将被宏“消耗”的参数。然后( list += sizeof(mode) )
之前的(mode *)
转换将指针转换为指向所需类型。但是,由于+=
,它现在指向所需参数之后。而这个指针值是+=
表达式和强制转换的结果。因此,它后面的[-1]
用于提取list
指向的位置之前的元素。我怀疑使用
[-1]
的这种略微笨拙的构造是为了避免在宏中两次使用list
,这是避免多次计算副作用的好做法,以防宏参数是一个具有副作用的表达式。请注意,在
list += sizeof(mode)
中使用list
可能是一个错误或疏忽;它应该是(list) += sizeof(mode)
。