C performs data-type conversions in the following four situations:
char
,
short
, and float
are passed to a
function using the old style declaration.
The following sections describe how operands and function arguments are converted.
The following rules-referred to as the usual arithmetic conversions- govern the conversion of all operands in arithmetic expressions. The effect is to bring operands to a common type, which is also the type of the result. The rules govern in the following order:
long double
, the
other operand is converted to long double
.
double
, the other operand is converted to double
.
float
,
the other operand is converted to float
.
unsigned long
int
, the other operand is converted to unsigned
long int
.
long
int
and the other has type unsigned int
,
and if a long int
can represent all values of an
unsigned int
, the operand of type unsigned
int
is converted to long int
. If a
long int
cannot represent all the values of an
unsigned int
, both operands are converted to
unsigned long int
. long
int
, the other operand is converted to long
int
.
unsigned
int
, the other operand is converted to unsigned
int
.
int
.
The following sections elaborate on the usual arithmetic conversion rules.
A
This implementation of integral promotion is called value
preserving, as opposed to unsigned preserving in which
To help locate arithmetic conversions that depend on unsigned
preserving rules, DEC C, with the check
option enabled, flags any integral promotions of
All other arithmetic types are unchanged by the integral promotions.
In DEC C, variables of type
This code assigns hex 41 (char
, short int
, or int
bit field, either signed or unsigned, or an object that has
enumeration type, can be used in an expression wherever an
int
or unsigned int
is permitted. 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 conversion rules
are called the integral promotions.
unsigned char
and unsigned short
widen to
unsigned int
. DEC C uses value-
preserving promotions, as required by the ANSI C standard, unless
the common C mode is specified.
unsigned
char
and unsigned short
to int
that could be affected by the value-preserving approach for integral
promotions.
char
are bytes treated as signed integers. When a longer integer is
converted to a shorter integer or to char
, it is
truncated on the left; excess bits are discarded. For example:
int i;
char c;
i = 0xFFFFFF41;
c = i;
'A'
) to c
.
The compiler converts shorter signed integers to longer ones by sign
extension.
Conversions also take place between the various kinds of integers.
When a value with an integral type is converted to another integral
type (such as int
converted to long int
) and the value can be represented by the new type, the value is
unchanged.
When a signed integer is converted to an unsigned integer of equal or greater size, and the signed integer value is nonnegative, its value is unchanged. If the signed integer value is negative, then:
When an integer value is demoted to an unsigned integer of smaller size, the result is the nonnegative remainder of the value divided by the number one greater than the largest representable unsigned value for the new integral type.
When an integer value is demoted to a signed integer of smaller size, or an unsigned integer is converted to its corresponding signed integer, the value is unchanged if it is small enough to be represented by the new type. Otherwise, the result is truncated; excess high-order bits are discarded and precision is lost.
Conversion between integral types of the same size, whether signed or unsigned, results in no machine-level representation change.
When a floating-type operand is converted to an integer, the
fractional part is discarded.
When a floating-type value is to be converted at compile time
to an integer or another floating type, and the result cannot
be represented, the compiler reports a warning in the following
instances:
When a value of integral type is converted to floating type, and
the value is in the range of values that can be represented, but not
exactly, the result of the conversion is either the next higher or
next lower value, whichever is the natural result of the conversion
on the hardware. See your DEC C documentation
for the conversion result on your platform.
unsigned int
and the
result cannot be represented by the unsigned int
type.
unsigned
int
, and the result cannot be represented by the
int
type.
If an operand of type float
appears in an expression,
it is treated as a single-precision object unless the expression
also involves an object of type double
or long
double
, in which case the usual arithmetic conversion
applies.
When a float
is promoted to double
or
long double
, or a double
is promoted to
long double
, its value is unchanged.
The behavior is undefined when a
If the value being converted is inside the range of values that can
be represented, but not exactly, the result is rounded to either the
next higher or next lower representable double
is demoted
to float
, or a long double
to
double
or float
, if the value being
converted is outside the range of values that can be represented.
float
value.
Although two types (for example, int
and
long
) can have the same representation, they are
still different types. This means that a pointer to int
cannot be assigned to a pointer to long
without using
a cast. Nor can a pointer to a function of one type be assigned to
a pointer to a function of a different type without using a cast.
In addition, pointers to functions that have different parameter-
type information, including the old-style absence of parameter-
type information, are different types. In these instances, if a
cast is not used, the compiler issues an error. Because there are
alignment restrictions on some target processors, access through
an unaligned pointer can result in a much slower access time or a
machine exception.
A pointer to void
can be converted to or from a pointer
to any incomplete or object type. If a pointer to any incomplete or
object type is converted to a pointer to void
and back,
the result compares equal to the original pointer.
An integral constant expression equal to 0, or such an expression
cast to the void *
type, is called a null pointer
constant. If a null pointer constant is assigned to or compared
for equality with a pointer, the constant is converted to a pointer
of that type. Such a pointer is called a null pointer,
and is guaranteed to compare unequal to a pointer to any object or
function.
An array designator is automatically converted to a pointer to the array type, and the pointer points to the first element of the array.
The data types of function arguments are assumed to match the types of the formal parameters unless a function prototype declaration is present. In the presence of a function prototype, all arguments in the function invocation are compared for assignment compatibility to all parameters declared in the function prototype declaration. If the type of the argument does not match the type of the parameter but is assignment compatible, C converts the argument to the type of the parameter (see Section 6.10.1). If an argument in the function invocation is not assignment compatible to a parameter declared in the function prototype declaration, an error message is generated.
If a function prototype is not present, all arguments of type
float
are converted to double
, all
arguments of type char
or short
are
converted to type int
, all arguments of type
unsigned char
and unsigned short
are
converted to unsigned int
, and an array or function
name is converted to the address of the named array or function.
The compiler performs no other conversions automatically, and any
mismatches after these conversions are programming errors.
A function designator is an expression that has function
type. Except when it is the operand of the sizeof
operator or the unary & operator, a function designator with type
"function returning type" is converted to an expression
that has type "pointer to function returning type."