Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Compiler bug?

Author: Dann Corbit

Date: 13:44:03 07/03/02

Go up one level in this thread


On July 03, 2002 at 16:09:37, Sune Fischer wrote:

>Hi quick question.
>
>// this one is "faulty":
>#define RANK64(r) (0x00000000000000FF<<(r<<3))  // r is 0-7
>
>// this one works:
>#define RANK64(r) (0x00000000000000FF<<((UINT64)r<<3))  // r is 0-7
>
>Q: Why do need I to cast the shifting parameter also, it's always a number
>between 0 and 63, isn't that obvious to the compiler (msvc++ 6)?

Programmer error.  You have two operands, neither of which requires 64 bit
integer type storage.  The leading zeros on the 255 do not change its type.

From the ISO C standard:

6.3.1 Arithmetic operands
6.3.1.1 Boolean, characters, and integers
1 Every integer type has an integer conversion rank defined as follows:
— No two signed integer types shall have the same rank, even if they hav e the
same representation.
— The rank of a signed integer type shall be greater than the rank of any signed
integer type with less precision.
— The rank of long long int shall be greater than the rank of long int, which
shall be greater than the rank of int, which shall be greater than the rank of
short int, which shall be greater than the rank of signed char.
— The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type, if any.
— The rank of any standard integer type shall be greater than the rank of any
extended integer type with the same width.
— The rank of char shall equal the rank of signed char and unsigned char.
— The rank of _Bool shall be less than the rank of all other standard integer
types.
— The rank of any enumerated type shall equal the rank of the compatible integer
type (see 6.7.2.2).
— The rank of any extended signed integer type relative to another extended
signed integer type with the same precision is implementation-defined, but still
subject to the other rules for determining the integer conversion rank.
— For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2
has greater rank than T3, then T1 has greater rank than T3.
2 The following may be used in an expression wherever an int or unsigned int may
be used:
— An object or expression with an integer type whose integer conversion rank is
less than the rank of int and unsigned int.
— A bit-field of type _Bool, int, signed int, or unsigned int.
If an int can represent all values of the original type, the value is converted
to an int; otherwise, it is converted to an unsigned int. These are called the
integer promotions.48) All other types are unchanged by the integer promotions.
3 The integer promotions preserve value including sign. As discussed earlier,
whether a ‘‘plain’’ char is treated as signed is implementation-defined.
Forward references: enumeration specifiers (6.7.2.2), structure and union
specifiers (6.7.2.1).
6.3.1.2 Boolean type
1 When any scalar value is converted to _Bool, the result is 0 if the value
compares equal to 0; otherwise, the result is 1.
6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted to another integer type other than
_Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly
adding or subtracting one more than the maximum value that can be represented in
the new type until the value is in the range of the new type.49)
3 Otherwise, the new type is signed and the value cannot be represented in it;
either the result is implementation-defined or an implementation-defined signal
is raised.

Footnotes:
48) The integer promotions are applied only: as part of the usual arithmetic
conversions, to certain argument expressions, to the operands of the unary +, -,
and ~ operators, and to both operands of the shift operators, as specified by
their respective subclauses.
49) The rules describe arithmetic on the mathematical value, not the value of a
given type of expression. 50) The remaindering operation performed when a value
of integer type is converted to unsigned type need not be performed when a value
of real floating type is converted to unsigned type. Thus, the range of portable
real floating values is (-1, Utype_MAX+1).

6.5.7 Bitwise shift operators

Syntax
1 shift-expression:
additive-expression
	shift-expression << additive-expression
	shift-expression >> additive-expression

Constraints
2 Each of the operands shall have integer type.

Semantics
3 The integer promotions are performed on each of the operands. The type of the
result is that of the promoted left operand. If the value of the right operand
is negative or is greater than or equal to the width of the promoted left
operand, the behavior is undefined.
4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are
filled with zeros. If E1 has an unsigned type, the value of the result is E1 ´
2E2, reduced modulo one more than the maximum value representable in the result
type. If E1 has a signed type and nonnegative value, and E1 ´ 2E2 is
representable in the result type, then that is the resulting value; otherwise,
the behavior is undefined.
5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an
unsigned type or if E1 has a signed type and a nonnegative value, the value of
the result is the integral part of the quotient of E1 / 2E2. If E1 has a signed
type and a negative value, the resulting value is implementation-defined.


6.6 Constant expressions
Syntax
1 constant-expression:
	conditional-expression
Description
2 A constant expression can be evaluated during translation rather than runtime,
and accordingly may be used in any place that a constant may be.

Constraints
3 Constant expressions shall not contain assignment, increment, decrement,
function-call, or comma operators, except when they are contained within a
subexpression that is not
evaluated.95)
4 Each constant expression shall evaluate to a constant that is in the range of
representable values for its type.

Semantics
5 An expression that evaluates to a constant is required in several contexts. If
a floating expression is evaluated in the translation environment, the
arithmetic precision and range shall be at least as great as if the expression
were being evaluated in the execution environment.
6 Aninteger constant expression96) shall have integer type and shall only have
operands that are integer constants, enumeration constants, character constants,
sizeof expressions whose results are integer constants, and floating constants
that are the immediate operands of casts. Cast operators in an integer constant
expression shall only convert arithmetic types to integer types, except as part
of an operand to the sizeof operator.
7 More latitude is permitted for constant expressions in initializers. Such a
constant expression shall be, or evaluate to, one of the following:
— an arithmetic constant expression,
— a null pointer constant,
— an address constant, or
— an address constant for an object type plus or minus an integer constant
expression.
8 An arithmetic constant expression shall have arithmetic type and shall only
have operands that are integer constants, floating constants, enumeration
constants, character constants, and sizeof expressions. Cast operators in an
arithmetic constant expression shall only convert arithmetic types to arithmetic
types, except as part of an operand to a sizeof operator whose result is an
integer constant.
9 Anaddress constant is a null pointer, a pointer to an lvalue designating an
object of static storage duration, or a pointer to a function designator; it
shall be created explicitly using the unary & operator or an integer constant
cast to pointer type, or implicitly by the use of an expression of array or
function type. The array-subscript [] and member-access .  and -> operators, the
address & and indirection * unary operators, and pointer casts may be used in
the creation of an address constant, but the value of an object shall not be
accessed by use of these operators.
10 An implementation may accept other forms of constant expressions.
11 The semantic rules for the evaluation of a constant expression are the same
as for nonconstant expressions.97)
Forward references: array declarators (6.7.5.2), initialization (6.7.8).

Footnotes:
95) The operand of a sizeof operator is usually not evaluated (6.5.3.4).
96) An integer constant expression is used to specify the size of a bit-field
member of a structure, the value of an enumeration constant, the size of an
array, or the value of a case constant. Further constraints that apply to the
integer constant expressions used in conditional-inclusion preprocessing
directives are discussed in 6.10.1.
97) Thus, in the following initialization,
static int i = 2 || 1 / 0;
the expression is a valid integer constant expression with value one.




This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.