Microchip Technology SW006022-1N Data Sheet

Page of 338
MPLAB
®
 XC16 C Compiler User’s Guide
DS52071B-page 100
 2012 Microchip Technology Inc.
Take care when comparing (subtracting) pointers. For example:
if(cp1 == cp2)
  ; take appropriate action
The ANSI C standard only allows pointer comparisons when the two pointer targets are 
the same object. The address may extend to one element past the end of an array.
Comparisons of pointers to integer constants are even more risky, for example:
if(cp1 == 0x246)
  ; take appropriate action
A NULL pointer is the one instance where a constant value can be safely assigned to a 
pointer. A NULL pointer is numerically equal to 0 (zero), but since they do not guarantee 
to point to any valid object and should not be dereferenced, this is a special case 
imposed by the ANSI C standard. Comparisons with the macro NULL are also allowed.
6.7
COMPLEX DATA TYPES
The compiler supports complex data types. You can declare both complex integer 
types and complex floating types, using the keyword __complex__. 
For example, __complex__ float x; declares x as a variable whose real part and 
imaginary part are both of type float. __complex__ short int y; declares y to 
have real and imaginary parts of type short int.
To write a constant with a complex data type, use the suffix ‘i’ or ‘j’ (either one; they 
are equivalent). For example, 2.5fi has type __complex__ float and 3i has type 
_ _complex_ _ int
. Such a constant is a purely imaginary value, but you can form 
any complex value you like by adding one to a real constant. 
To extract the real part of a complex-valued expression exp, write __real__ exp
Similarly, use __imag__ to extract the imaginary part. For example;
        
_ _
complex
_ _
 float z;
        float r;
        float i;
        r = 
_ _
real
_ _
 z;
        i = 
_ _
imag
_ _
 z;
The operator, ~, performs complex conjugation when used on a value with a complex 
type. 
The compiler can allocate complex automatic variables in a noncontiguous fashion; it’s 
even possible for the real part to be in a register while the imaginary part is on the stack 
(or vice-versa). The debugging information format has no way to represent noncontig-
uous allocations like these, so the compiler describes noncontiguous complex 
variables as two separate variables of noncomplex type. If the variable’s actual name 
is foo, the two fictitious variables are named foo$real and foo$imag.