From: SourceForge.net <no...@so...> - 2008-02-04 08:53:08
|
Bugs item #1874922, was opened at 2008-01-18 18:55 Message generated for change (Comment added) made by bortel You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1874922&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: C-Front End Group: None Status: Open Resolution: None Priority: 7 Private: No Submitted By: Laszlo BORTEL (bortel) Assigned to: Borut Ražem (borutr) Summary: explicit typecast is ineffective for unsigned char parameter Initial Comment: The compiler seems to ignore the explicit (unsigned char) typecast when it is applied to the actual parameter of a function with variable arguments. (Explicit (unsigned char) typecast is necessary even for unsigned char type otherwise the compiler would automatically push a two byte integer onto the stack.) The bug for example blocks the use of printf() function with "%bu" format specifier. C:\>sdcc -v SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.4 #4972 (Nov 23 2007) (MINGW32) C:\>ver Microsoft Windows XP [Version 5.1.2600] ---------------------------------------------------------------------- >Comment By: Laszlo BORTEL (bortel) Date: 2008-02-04 09:53 Message: Logged In: YES user_id=1063737 Originator: YES Hi All, I am not familiar with different standards of the C language - so I will not bring you such counter argument. The problem I raised is very practical: I just wanted to use the %b formatter with char argument in the printf() function. Then I realised: sometimes it is possible with explicit typecast, sometimes it is not. My argument to support my interpretation is that it is better to leave control in the hand of the programmer and consistently let him override automatic promotion if he wishes so than deprive him of this possibility and drop this neat feature of byte-sized arguments in print formatting. I think it is not easy to decide between my practical and Borut's pragmatic interpretation. One idea: isn't it feasible to introduce a command-line switch for the compiler to select between the two possible consistent behaviours? (--explicit-typecast-overrides-automatic-promotion). Regards, Laszlo ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2008-02-03 18:53 Message: Logged In: YES user_id=888171 Originator: NO I agree that ellipis parameters should be cast up to int. Mainly because I don't see how to solve this otherwise without losing other optimizations. The price to be paid is unnecessary upcasts when printing char values. This also means that the SDCC specific %b formatter becomes useless (see also regression test snprintf.c) and that the manual must be updated (1.4 Compatibility with previous versions). ---------------------------------------------------------------------- Comment By: Borut Ražem (borutr) Date: 2008-02-03 13:37 Message: Logged In: YES user_id=568035 Originator: NO An other indication that I might be right is: "In function calls not in the scope of a function prototype, integer arguments have the integer promotions applied and float arguments are widened to double. *It is not possible in such a call to pass an unconverted char or float argument.*" as stated in Rationale for International Standard — Programming Languages — C, Revision 5.10, April-2003, chapter 6.7.5.3p15. The document can be found at: http://www.open-std.org/JTC1/SC22/WG14/www/docs/C99RationaleV5.10.pdf Borut ---------------------------------------------------------------------- Comment By: Borut Ražem (borutr) Date: 2008-02-03 13:11 Message: Logged In: YES user_id=568035 Originator: NO Hi Laszlo, my interpretation of the standard is different of yours: I think that explicit casting to unsigned char shouldn't change anything: the argument has still to be promoted to an int, as required by the integer promotion rule, which says that *in the absence of a function prototype*, _Bool, char and short are promoted either to int or unsigned int when used as, or in, function arguments. But I agree that there is a bug in SDCC. I think that we need an additional opinions to decide what is right and what is wrong before fixing anything. SDCC developers and users: can you help us here? My interpretation is as follows: --8<--------------- void printf(char* str, ...) {str;} struct { unsigned char d; } s={0x78}; unsigned char d=0x89; void main (void) { unsigned char c=0x56; unsigned int u=0x1234; //correct: neither explicit typecast, nor automatic promotion printf ("%u", u); //buggy: explicit typecast shuld not override automatic promotion to integer printf ("%bu", (unsigned char)u); //correct: automatic promotion to integer is performed printf ("%u", c); //correct: explicit typecast doesn't override automatic promotion to integer printf ("%bu", (unsigned char)c); //buggy: explicit typecasts (doesn't matter how many they are) should not override automatic promotion to integer printf ("%bu", (unsigned char)(unsigned int)c); //correct: automatic promotion to integer is performed on static variable printf ("%u", d); //correct: explicit typecast doesn't override automatic promotion to integer printf ("%bu", (unsigned char)d); //correct: automatic promotion to integer is performed printf ("%u", s.d); //buggy: explicit typecast should not override automatic promotion to integer printf ("%bu", (unsigned char)s.d); } -->8--------------- Borut ---------------------------------------------------------------------- Comment By: Laszlo BORTEL (bortel) Date: 2008-02-02 18:49 Message: Logged In: YES user_id=1063737 Originator: YES File Added: BugReport18c.lst ---------------------------------------------------------------------- Comment By: Laszlo BORTEL (bortel) Date: 2008-02-02 18:47 Message: Logged In: YES user_id=1063737 Originator: YES Hi Borut, let me add one more important bit of information to this bug report. In the extended file "BugReport18c.c" it can be seen that explicit (unsigned char) typecast is NOT effective for static variable 'unsigned char d', but effective for static structure member 'unsigned char s.d', which is shocking, because both d and s.d are of the same type, so there sould be no diffrence in their treatment. I would expect consistent behaviour in all the cases listed in the 'BugReport18c.c' file: the compiler should apply default argument promotion according to ISO/IEC 9899 UNLESS there is an explicit typecast in the actual parameter list of the function, in which case the explicit typecast should override/supress default argument promotion. What I expect is not against the mentioned standard, so I ask you to reconsider your opinion and correct the bug. Regards, Laszlo File Added: BugReport18c.c ---------------------------------------------------------------------- Comment By: Laszlo BORTEL (bortel) Date: 2008-01-21 14:41 Message: Logged In: YES user_id=1063737 Originator: YES File Added: BugReport18b.lst ---------------------------------------------------------------------- Comment By: Laszlo BORTEL (bortel) Date: 2008-01-21 14:40 Message: Logged In: YES user_id=1063737 Originator: YES Dear Borut, While understanding your reference to the ISO/IEC 9899 standard I still think that there is a bug somewhere around. Please take a look at the new file "BugReport18b.c" that I added. It seems that the default argument promotion from unsigned char to int can be supressed by explicit (unsigned char) typecast when the actual parameter is unsigned int (variable u in the file) and can't be supressed when the actual parameter is unsigned char (variable c in the file). Explicit double-typecast (see last printf(); call) can be used as workaround, but it should not be necessary in my opinion. Regards, Laszlo File Added: BugReport18b.c ---------------------------------------------------------------------- Comment By: Borut Ražem (borutr) Date: 2008-01-19 13:57 Message: Logged In: YES user_id=568035 Originator: NO Hi Laszlo, I think that the behavior is correct: unsigned char is promoted to int. See ISO/IEC 9899 standard, chapter 6.5.2.2 Function calls, item #6: "If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. ..." In item #7 is written: "... The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments. ..." Which exactly explains your case. Borut ---------------------------------------------------------------------- Comment By: Laszlo BORTEL (bortel) Date: 2008-01-19 11:38 Message: Logged In: YES user_id=1063737 Originator: YES I have increased the priority from the default and attached the list file. >From the file it can be seen that the compiler generates absolutely the same code for parameter passing in both cases. Two bytes pushed onto the stack for unsigned char variable: 0008 146 _main: 147 ; BugReport18.c:5: printf ("%u", u);//correct 0008 74 01 148 mov a,#0x01 000A C0 E0 149 push acc 000C E4 150 clr a 000D C0 E0 151 push acc 000F 74r00 152 mov a,#__str_0 0011 C0 E0 153 push acc 0013 74s00 154 mov a,#(__str_0 >> 8) 0015 C0 E0 155 push acc 0017 74 80 156 mov a,#0x80 0019 C0 E0 157 push acc 001B 12s00r00 158 lcall _printf 001E E5 81 159 mov a,sp 0020 24 FB 160 add a,#0xfb 0022 F5 81 161 mov sp,a 162 ; BugReport18.c:6: printf ("%bu", (unsigned char)u);//buggy 0024 74 01 163 mov a,#0x01 0026 C0 E0 164 push acc 0028 E4 165 clr a 0029 C0 E0 166 push acc 002B 74r03 167 mov a,#__str_1 002D C0 E0 168 push acc 002F 74s00 169 mov a,#(__str_1 >> 8) 0031 C0 E0 170 push acc 0033 74 80 171 mov a,#0x80 0035 C0 E0 172 push acc 0037 12s00r00 173 lcall _printf 003A E5 81 174 mov a,sp 003C 24 FB 175 add a,#0xfb 003E F5 81 176 mov sp,a 0040 22 177 ret File Added: BugReport18.lst ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1874922&group_id=599 |