Zach Welch wrote: > On Fri, 2009-06-19 at 20:31 -0400, Duane Ellis wrote: > >> duane> FYI - I committed several cygwin specific printf() warning fixes. >> duane> Simple cast to fix >> duane> these where causing "-Werror" failures on cygwin. >> >> zach> I was just about to post some patches to show how to fix all of these >> zach> correctly, as casts are not the right way to do it. >> >> In some cases, I can agree, but in others - I don't agree. A cast is by >> far the most simplest solution. >> >> For instance, look at this: >> >> LOG_WARNING("writing %d bytes only - as image section is %d >> bytes and bank is only %d bytes", \ >> (int)(c->base + c->size - run_address), >> (int)(run_size), (int)(c->size)); >> >> (a) look at what is being printed >> (b) the possible ranges of numbers >> (c) the number of parameters involved in the expressions >> >> At some point - having to dig back 20 to 30 -lines- to *random* places - >> because some variables are: >> >> (1) function parameters >> (2) defined at the top most block >> (3) defined locally to the local block >> (4) defined a few lines down from the top most block >> (5) often simplistic 'i/j/k' type vars that are reused because they are >> handy. >> (6) By the time I personally dig through the above, and determine all >> types involved >> (7) Then understand the underlying arithmetic integer promotion order... >> *note* this set of equations are simple... >> (8) a cast to a basic type is truly a very *simple* solution, >> (9) a cast to a basic type in this case is the K.I.S.S. solution. >> >> Either that - or we *need* a different solution here, the above is absurd. >> >> Comments? >> > > The simple solution is not the correct one in this case. The problem > is that your assumptions about ranges are not portable; that is the > point in using these macros. > >
==== You miss an important point, it is *NOT* the possible range of values the *TYPE* may take on. It is the range of values the **ACTUAL*DATA** might take on that is important here. Consider: uint32_t x; void funny_function( uint32_t ); for( x = 0 ; x < 10 ; x++ ){ printf(" X = %d, Calling funny function\n", (int)(x)); funny_function( x ) ; } In the above, I have several choices, (a) I could have used an "int" variable - then *cast* it to a uint32_t at the function call (note here: I am partial to x as a loop control variable, others like i/j/k) or - because (b) the value will never be negative, I just choose 'uint32_t' because it was convient. Is the printf() statement *WRONG* - or is the printf() statement *CORRECT* in this senario. ==== If we had to fix this, what would we do to fix this: Today - we do not have macros, or types like GDB/GCC/GAS. GDB for instance uses CORE_ADDR - and has infrastructure behind it. Here, under OpenOCD we generally: (1) assume that all embedded openocd targets are *32bit* at most... (2) assume all host platforms are at least 32bit host platforms (3) and thus, target addresses are generally equal to - or smaller then the host "unsigned integers" (4) In most, if not all of the "u32" cases, the format string specifies "%08x" or equal. Are these assumptions *wrong*? If so, we have major other problems we must deal with. ==== There are numerous examples of this where - for instance the code does the following: LOG_ERROR("Verfication error address 0x%08x, read back 0x%02x, expected 0x%02x", address + wrote + i, readback[i], chunk[i]); In this specific case, the *correct* fix is something else. The "address" parameter really needs a *function* that handles the width value. Otherwise, a "64bit" target will not work. We are not proposing to fix these situations today are we? Doing so would really be better served by a function something like: char *target_address_as_hex( CORE_ADDR address_value ); One can 'question' the two 8bit values printed, allow me to make my point another way. ==== Here is another example: LOG_INFO( "device id = 0x%08x (manuf 0x%03x dev 0x%02x, ver 0x%03x)", device_id, (device_id>>1)&0x7ff, (device_id>>12)&0xff, (device_id>>20)&0xfff ); The format strings alone tell me that a 32bit unsigned *INTEGER* is sufficient. As does the math operators. Since our *basic* assumption of the host platform is at least a "32bit unsigned int" A simple cast is valid here. Are you suggesting that our *basic* host assumption is wrong? ==== duane> 9) a cast to a basic type in this case is the K.I.S.S. solution.duane> zach> I don't care one white about KISS if the code is wrong. Is this a pedantic position/point you are trying to make? The code today has *major* problems if/when we have a 64bit target. The code is more *wrong* when we have 32bit hosts and 64bit targets. -Duane. _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development