TYPES(2) TYPES(2) NAME types - c type system SYNOPSIS char, short, int, vlong uchar, ushort, uint, uvlong u8int, u16int, u32int, u64int Rune usize, uintptr uintmem schar DESCRIPTION The Plan 9 C compilers and system use a specialization of the C99 type system, which has evolved over time. The com- pilers are unsigned preserving, and char can be assumed to be a signed value. Although the system currently makes heavy use of ulong to represent exactly-32-bit integers and pointers as unsigned integers, this practice is no longer supportable with the advent of true 64-bit compilers. Hav- ing a more explicit type set permits us to be more specific about intent and is helpful to maintain portability to other systems, especially Plan 9 from User Space. The basic 8, 16, 32 and 64-bit types are char, short, int, and vlong. Conventionally, unsigned types simply prepend a "u" to the basic type name rather than using the unsigned prefix. Most programs will need no more integer types than this. Exceptions come in two forms: the need to be specific about use to aid in porting, and type widths fixed by hardware or protcols. The system call interface does not fit the second case since the compiler itself will pick the same sizes for both kernel and user space. To specify an integer of a particular width, the form ubitsint is used. Types for 8, 16, 32, and 64 bit-width specific unsigned integers are available. There are no signed variants of these as they are not useful where size- specific types are appropriate. As a special case, uchar is assumed to be equivalent to u8int. Beware of using size- specific integers in a structure as a marshalling technique. The compiler is free to pad the structure and endian Page 1 Plan 9 (printed 12/21/24) TYPES(2) TYPES(2) conversion can easily be forgotten. Consider using a struc- ture of basic types (typically uchar) marshalled with func- tions as in getbe(2). The Rune type stands alone. It holds a single unicode code- point as described in rune(2) and utf(6). The use-specific types are usize and uintptr. Usize repre- sents the type returned by the C sizeof operator. It is typically the same width as a virtual address. In order to ease the transition to 64-bits, the AMD64 compiler currently uses a 32-bit usize. An integer representation of a virtual-address pointer is represented by the type uintptr. The kernel additionally needs to specify a type to represent a physical address. Since physical addresses may be the same size, larger (PAE) or smaller than virtual addresses, uintmem as a physical address may be the same size, larger (PAE), or smaller than a virtual address. Uintmem also stores the sizes of things that uintmem might address. Finally, schar is used when porting to other systems where it may matter. It should not generally be used. EXAMPLES The C library has a number of functions which are in need of conversion. For example, void* malloc(usize nbytes); int segfree(void *va, usize len); uintptr getcallerpc(void*); A device driver might access a 32-bit register with u32int regval; regval = regbase[regoff/4]; In the kernel we could convert between physical and virtual addresses this way: uintmem upaddr(uintptr kva); uintptr upaddr(uintmem pa); The actual functions use void* for kernel addresses. SEE ALSO 8c(1), getbe(2), rune(2), utf(6), Plan 9 from User Space, http://swtch.com/plan9port BUGS The spirit of the original type system has faded with time. Page 2 Plan 9 (printed 12/21/24)