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
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development