This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: need help for arithmetic conversion about gcc


On 12/14/2010 9:44 PM, Ian Lance Taylor wrote:
stephen<chency666@gmail.com> writes:

I am trying to figure out the rules of arithmetic conversion in gcc.
gcc as such does not implement any particular rules.  You seem to be
discussing the rules of arithmetic conversion in C.  Those rules are set
by the C standard, and gcc implements what the standard says when
compiling C code.


In my previous understanding, suppose there are two operands with the
different data type, the operand with less integer conversion rank
would be converted to the type of the operand with greater rank. But I
found it does not work like that in gcc. Take the following statements
as an example,

short ilval irval;
long lval;
ilval = lval + irval;

In this case, both lval and ilval are converted to "short unsigned
int", the result of "(short unsigned int) lval+(short unsigned int)
irval" is then converted to "short int". I found the coversion notes
from the RTL codes' file. The corresponding informations is given
below:

;; D.1528 = (short unsigned int) lval
;; irval.0 = (short unsigned int) irval
;; D.1530 = D.1528 + irval.0
;; ilval = (short int) D.1530

The part which confuses me is that the operand "lval" is converted
from a type with greater rank (i.e., long ) to a type with less rank
(i.e., short unsigned int ).
Your test case has a syntax error and is incomplete.  However, the
answer to your implied question is that the assignment to ilval is going
to truncate the result to "short int".  So gcc doesn't have to compute
more than 16 bits of the result anyhow (assuming you are using a typical
platform where short is 16 bits).  This is following the "as if" rule in
the standard, which says that the compiler can generate any sequence of
code which behaves as if the exact rules in the standard were followed.


I see this as one more example where it's better to explicitly show each
step that you intend in your algorithm. (NB: I grew up as an assembly
language programmer, so this is natural to me.)

I would probably do something like:

short int ilval, irval;
long int lval, ltemp;

ltemp = lval + (long int) irval;
ilval = (short int) ltemp;

probably with comments explaining to the maintenance programmer
(perhaps me in a few weeks) why I've done this.

In my 50 years of programming I've had many programmers tell me
that they use implicit casting, side effects in Boolean
expressions, etc., because "it's more efficient." When looking
at the generated assembly language I've yet to see a case
when that's true. Also, unless this code is in a long loop,
it probably isn't worth optimizing it for speed.

--Bob



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]