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.