升级NC30 M16 C编译器:va_arg问题
Upgrading NC30 M16 C Compiler: va_arg issue
在我的NC30 M16C编译器版本5中,我有以前的程序员使用的以下宏。我们在"printf()"、"sprintf()"等函数中使用这些宏。
typedef unsigned char * va_list;
#define va_start( args, first ) args = (va_list) ( (unsigned short) &first + sizeof( first ) )
#define va_arg( args, type ) *( (type *) args )++
#define va_end( args )
当我用NC30 M16C编译器版本6编译此代码时,它会给我错误"无效左值"。以下是整个错误消息的一部分:
clib.c(253) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
clib.c(293) : C2700 (E) invalid lvalue
===> fch = va_arg( args, far char * );
clib.c(299) : C2700 (E) invalid lvalue
===> nch = va_arg( args, char * );
clib.c(305) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
clib.c(323) : C2700 (E) invalid lvalue
===> ulong = va_arg( args, unsigned long );
clib.c(341) : C2700 (E) invalid lvalue
===> llong = va_arg( args, unsigned long long );
clib.c(359) : C2700 (E) invalid lvalue
===> ulong = va_arg( args, unsigned long );
clib.c(377) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned short );
clib.c(382) : C2700 (E) invalid lvalue
===> ft = va_arg( args, float );
clib.c(519) : C2694 (E) unknown variable source
===> *source++ = zeropad ? '0' : ' ';
clib.c(527) : C2694 (E) unknown variable source
===> *source++ = '%';
clib.c(532) : C2700 (E) invalid lvalue
===> snum = va_arg( args, signed int );
clib.c(550) : C2694 (E) unknown variable source
===> *source++ = *tempptr;
clib.c(556) : C2700 (E) invalid lvalue
===> fch = va_arg( args, far char * );
clib.c(558) : C2694 (E) unknown variable source
===> *source++ = *fch++;
clib.c(564) : C2700 (E) invalid lvalue
===> nch = va_arg( args, char * );
clib.c(566) : C2694 (E) unknown variable source
===> *source++ = *nch++;
clib.c(572) : C2700 (E) invalid lvalue
===> unum = va_arg( args, unsigned int );
这是我们使用这些micros的函数之一。此函数与"printf"是相同的函数,但将其命名为zwPrintf():
int zwPrintf( far char * format, ... ) {
zwVAList args;
unsigned int unum;
unsigned char temp[ FIELD_BUFF_SIZE + 1 ]; /* for formatting numbers (max length for long decimal) */
unsigned char * tempptr;
int zeropad, minfield, counter;
far char * fch;
char * nch;
unsigned long ulong;
int negative;
float ft, mantissa;
unsigned long long llong;
//unsigned char mychar;
//unsigned char *mychar_p;
//unsigned int *mytest_p;
va_start( args, format );
while( *format ) {
if( *format == '%' ) {
format++;
zeropad = 0;
minfield = 0;
negative = 0;
if( *format == '0' )
zeropad = 1; /* we want zero padding to field width */
while( *format >= '0' && *format <= '9' ) {
/* we are specifying field width */
minfield *= 10;
minfield += *format - '0';
format++;
}
if( minfield > FIELD_BUFF_SIZE ) { /* we want a field width greater than our field buffer, pad misc */
for( counter = 0; counter < minfield - FIELD_BUFF_SIZE; counter++ )
zwPutc( (unsigned char) ( zeropad ? '0' : ' ' ) );
minfield = FIELD_BUFF_SIZE;
}
switch( *format ) {
case '%': /* literal % */
zwPutc( '%' );
break;
case 'd': /* signed decimal output */
unum = va_arg( args, unsigned int ); /* pull unsigned, and do math ourselves (to avoid confusion) */
//mychar='a';
//mychar_p = &mychar;
//mytest_p = ((unsigned int*)mychar_p);
//mytest_p++;
//unum = *mytest_p;
//unum = (*((unsigned int*)args))++;
//unum = (*((unsigned int*)args))++;
/* convert to decimal (backward) */
if( unum >= 0x8000 ) { /* number is -'ve */
negative = 1;
unum = ~unum + 1; /* make number +'ve */
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( unum )
*tempptr-- = ( unum % 10 ) + '0';
else {
if( negative && ( zeropad == 0 ) ) {
*tempptr-- = '-';
negative = 0;
}
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
unum /= 10;
counter++;
} while( unum || counter < minfield );
/* output the string */
if( negative )
zwPutc( '-' );
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 's': /* far char * */
fch = va_arg( args, far char * );
while( *fch )
zwPutc( *fch++ );
break;
case 'S': /* near char * (extension) */
nch = va_arg( args, char * );
while( *nch )
zwPutc( *nch++ );
break;
case 'x': /* hexadecimal */
unum = va_arg( args, unsigned int );
/* convert to hexadecimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( unum )
*tempptr-- = zwHexToAsc( (unsigned char) unum & 0x0F );
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
unum >>= 4;
counter++;
} while( unum || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'i': /* unsigned long int decimal (extension) */
ulong = va_arg( args, unsigned long );
/* convert to decimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ulong )
*tempptr-- = (unsigned char)( ulong % 10 ) + '0';
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
ulong /= 10;
counter++;
} while( ulong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'L': /* unsigned long long decimal (extension) */
llong = va_arg( args, unsigned long long );
/* convert to decimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( llong )
*tempptr-- = (unsigned char)( llong % 10 ) + '0';
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
llong /= 10;
counter++;
} while( llong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'h': /* unsigned long int hexadecimal (extension) */
ulong = va_arg( args, unsigned long );
/* convert to hexadecimal (backward) */
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ulong )
*tempptr-- = zwHexToAsc( ( (unsigned char) ulong ) & 0x0F );
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
ulong >>= 4;
counter++;
} while( ulong || counter < minfield );
/* output the string */
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
break;
case 'c':
unum = va_arg( args, unsigned short );
zwPutc( (char) unum );
break;
case 'f':
ft = va_arg( args, float );
#if 0
/* convert to decimal (backward) */
if( ft < 0 ) { /* number is -'ve */
negative = 1;
ft = -ft;
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
/* split float to integer and mantissa part */
ulong = ft / 1;
mantissa = ft - ( float )ulong;
/* get integer part */
do {
if( ulong ){
*tempptr-- = (unsigned char)( ulong % 10 ) + '0';
}
else {
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
ulong /= 10;
counter++;
} while( ulong || counter < minfield );
if ( negative ) {
temp[ 0 ] = '-';
zwMemcpy( &temp[ 1 ], &temp[ FIELD_BUFF_SIZE - counter ], counter ); //change to right position
counter++;
}
else
zwMemcpy( &temp[ 0 ], &temp[ FIELD_BUFF_SIZE - counter ], counter );
temp[ counter++ ] = '.';
/* get mantissa part */
tempptr = &temp[ counter ];
do {
unum = ( mantissa * 10 ) / 1;
if( unum ){
*tempptr++ = (unsigned char)( unum ) + '0';
}
else {
*tempptr++ = '0';
}
mantissa = ( float ) ( mantissa * 10.0 - ( float )unum ) * 10.0;
counter++;
} while( mantissa > 0 || counter < minfield );
for( unum = 0; unum < counter; unum++ )
zwPutc( temp[ unum ] );
/* convert to decimal (backward) */
if( ft < 0 ) { /* number is -'ve */
negative = 1;
ft = -ft;
}
tempptr = &temp[ FIELD_BUFF_SIZE ];
counter = 0;
do {
if( ft >= 1.0 ){
*tempptr-- = ( ft % 10.0 ) + '0';
// *tempptr-- = ( ft * 10 - ( ( ft * 100 ) / 10 ) ) + '0';
}
else {
if( negative && ( zeropad == 0 ) ) {
*tempptr-- = '-';
negative = 0;
}
else
*tempptr-- = ( zeropad || counter == 0 ) ? '0' : ' ';
}
ft /= 10;
counter++;
} while( ft >= 1.0 || counter < minfield );
/* output the string */
if( negative )
zwPutc( '-' );
for( tempptr++; tempptr <= &temp[ FIELD_BUFF_SIZE ]; tempptr++ )
zwPutc( *tempptr );
#endif
break;
case 0: /* end of string (malformed string anyway) */
va_end( args );
return -1; /* error */
break;
}
}
else
zwPutc( *format );
format++;
}
va_end( args );
return -1;
}
请指导我,我该怎么做才能纠正这个问题。
提前谢谢。
你能试着替换吗:
#define va_arg( args, type ) *( (type *) args )++
带有
#define va_arg( args, type ) *( (type *) args ), args += sizeof (type)
说明:
您得到编译错误是因为以下表达式:
((type *) args )++
在C中无效:强制转换的结果不是左值,并且后缀++
运算符要求其操作数是左值。很多编译器对这个约束不严格,但显然你的编译器没有(或者新版本更严格)。
还需要注意的是,所提出的解决方法应该在您的程序中使用简单的赋值表达式,如:
unum = va_arg( args, unsigned int );
因为CCD_ 2具有比逗号运算符更高的优先级。
编辑:
另一个(也许更好的)解决方案:使用这个解决方案,您应该能够绕过强制转换的结果不是左值的事实:
#define va_arg( args, type ) *( *(type **) &args )++
相关文章:
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 将 N-arg 函数包装到另一个函数中
- 使用显式模板参数列表和 [temp.arg.explicit]/3 的函数调用的演绎失败
- 为什么不接受具有默认分配参数的函数作为 0-arg 生成器?
- C++重载解析总是诉诸别名 arg. 而不是其他人作为对所有人都有效的 arg.
- 区分两个零arg构造函数的惯用方法
- 将 mnist 客户端重写为 c++(arg[0] 不是矩阵)
- 在现代 c++ 中,有什么好方法可以获取 arg 类型列表表单函数指针吗?
- 如何使用 z3 中的 arg() 函数
- 为什么有必要将"this"指针作为"arg"参数传递给pthread_create
- 如何在数组中使用结构化绑定作为ARG传递给某些函数
- QSqlQuery 绑定值与 BindValues 与 QString.arg() 是否存在性能差异
- 在C 中,您可以创建一个对象作为arg function
- execve()的envp arg arm中的ld_library_path即使调用setuid part删除了其特权,
- C 预期字符串在ARG之前
- 传递variadic arg to模板函数时的汇编误差
- C++ 当函数 arg 类型为类接口时,无法传递对指针的引用
- 将数组传递给在 arg-list 中接受双指针的函数
- 功能指针(到其他内核)作为CUDA中的内核Arg
- 从 re2 Arg 中获取匹配的数据