在我的NC30 M16C編譯器版本5中,我使用了以前的程序員使用的以下宏。我們在「printf()」,「sprintf()」等函數中使用這個宏。升級NC30 M16 C編譯器:va_arg問題
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);
這裏是在其中我們使用這些萬分之一的功能中的一個。此功能是相同的功能的「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;
}
請指引我,我應該怎麼做才能解決這個問題。
在此先感謝。
顯示我們調用這些宏的代碼。 (我認爲你的實現不提供''?) –
2012-08-02 23:02:40
實際上錯誤消息是有道理的,gcc是這個鬆懈的,但是轉換的結果不是左值,所以postfix ++不能應用(違反約束)。 – ouah 2012-08-02 23:09:18
我在原來的帖子裏增加了一個功能,它使用這些micros。謝謝。 – user977601 2012-08-03 03:09:24