diff -r 51a74ef9ed63 -r ae94777fff8f Symbian3/SDK/Source/GUID-8675AC01-E2D8-425C-899F-12BE99345AA9.dita --- a/Symbian3/SDK/Source/GUID-8675AC01-E2D8-425C-899F-12BE99345AA9.dita Wed Mar 31 11:11:55 2010 +0100 +++ b/Symbian3/SDK/Source/GUID-8675AC01-E2D8-425C-899F-12BE99345AA9.dita Fri Jun 11 12:39:03 2010 +0100 @@ -1,163 +1,163 @@ - - - - - -C++ -and Machine ArchitectureThe C++ language, following its foundation in C, is close to the -machine architecture. This allows applications to be implemented efficiently, -but, especially for developers new to the language, presents some issues of -which you need to be aware. This topic reviews the basic language features -from this perspective, and discusses how the resulting issues are handled. -
Arithmetic types

An int is -usually implemented as the natural machine word size of the particular implementation. -This is 32 bits in most modern machines. It was 16 bits in older machines, -and in a few machines it may even be 64 bits.

Similarly, a pointer -(a void*, for instance) is usually implemented as a machine -word but, in some machines with special architectures, a pointer may be more -complex.

It is assumed that Symbian is implemented on a machine -with a 32-bit or greater machine word, and 32-bit pointers. The types TInt and TUint are typedefed onto the built-in int and unsigned int types, -and are guaranteed to be at least 32 bits.

When you need a specific -size, regardless of implementation, use a sized type. Several of these are -available:

- - - -

TInt32, TUint32

-

32-bit signed and unsigned integer

In each case, the -representation is a 32-bit machine word which, in the ARM architecture, must -be aligned to a four-byte boundary. The compiler ensures that this is always -the case.

-
- -

TInt8, TUint8, TText8

-

8-bit signed and unsigned integer, and 8-bit character

In -each case, the representation is an 8-bit byte, which has no specific alignment -requirements.

-
- -

TInt16, TUint16, TText16

-

16-bit signed and unsigned integer, and 16-bit character

In -each case, the representation is a 16-bit halfword, which should be aligned -to a two-byte boundary.

-
- -

TInt64, TUint64

-

64-bit signed and unsigned integer

These are typedefed -to appropriate built-in types for the compiler being used (long long, and -unsigned long long for ARM RVCT).

-
- -

TReal, TReal64

-

Double-precision floating point, IEEE754 64-bit representation - This is the floating-point type recommended for general use.

You -are recommended to perform operations in integer arithmetic if possible (for -instance, most GUI calculations), and to use floating-point only when the -problem demands it (for instance, a spreadsheet application).

On -processors that have floating point hardware, the compiler generates host -instructions which use that hardware directly. On processors which don't have -a floating point unit, the compiler implements the calculations in software. -

-
- -

TReal32

-

32-bit floating point

This is smaller and quicker, but -should only be used when space and/or time are at a true premium, as its precision -is unsatisfactory for many applications.

-
- - -
-
Compound types

Apart from classes, C++ inherits -from C various other types of compounding.

A struct maps an area -of memory:

struct TEg - { - TInt iInt; // offset 0, 4 bytes - TText8 iText; // offset 4, 1 byte - // 3 wasted bytes - TReal iReal; // offset 8, 8 bytes - } // total length = 16 bytes - -

Structures are regarded as T types: that is they -may not own heap-allocated resources such as C type classes. -

An array contains many built-ins or other types

TInt a[32]; // 32 TInts, = 128 bytes -S b[3]; // 3 Ss, = 48 bytes

The main disadvantage of using -C++ arrays is that there is no automatic checking of index values. For this -reason, and to support more complex containers, C++ has evolved the Standard -Template Library (STL). Symbian does not use STL, but provides its own range -of efficient container classes, for fixed, dynamic, and associative arrays. -For details, see Dynamic -Arrays.

-
Pointers

A pointer is a memory address. If you can -take the address of an object, then you can refer to it by pointer:

S* ps; // pointer to an S -ps=&s // take address of existing S -

A pointer is a 32-bit machine word, and could point to anything.

- -

The specifier is placed next to the type rather than the name.

There -is often a need to refer to memory as anything: for this, a void* pointer -is used in C++. In Symbian, a TAny* may be referred to instead. -A TAny* is a pointer to anything.

-
Strings

In C++, the basic string is an array of -characters:

char* hello="hello";

This statement -does two things: firstly, it sets aside six bytes of memory containing the -characters 'h', 'e', 'l', 'l', 'o', '\0'. Secondly, it sets the pointer hello -to contain the address of the first of those bytes.

- -

Functions accessing the string rely on this address as its starting -point, and the terminating \0 to indicate its end. Functions -which manipulate the string must either deliberately not extend it, or must -have some cue as to the amount of memory reserved for the string (beyond the -trailing\0) so they know how much it can be extended. This -leads to an awkward programming style, and every C++ library provides a way -to manipulate strings more elegantly. The Symbian platform solution is descriptors: -these are introduced in Descriptors

-
Functions

Functions are a piece of code which can -be called and executed from anywhere else in a program. The stack is used -to pass parameters and to contain local variables. The stack is often augmented -by machine registers, especially in a register-rich processor such as the -ARM, so that memory is often not used. But, conceptually, there is a stack, -and for the purposes of this explanation it is convenient to consider the -stack as if it were implemented entirely in memory.

Parameters are -passed by copying or evaluating onto the called functions stack frame. It -is bad practice to pass large parameters, such as an entire struct, or, in -fact, anything beyond two machine words in size, because this involves excessive -copying. Instead, a pointer or a reference should be used to pass the address, -instead of the data itself.

In a multi-tasking system such as Symbian, -each thread has its own stack, which is a pre-allocated area of memory. Each -function then allocates its own frame from the stack on entry, and de-allocates -it on exit. The advantage of the stack mechanism is that allocation and de-allocation -are very rapid indeed— just a couple of instructions. Also, the lifetime of -any variable on the stack is very well defined: it is the lifetime of its -owning function, or, in fact, its owning block, since functions may have blocks -within them.

When a function returns, its stack memory is still there: -it is just not allocated. The stack memory will be re-used by the next function -that is called. A potential source of error is to allocate an object on a -functions stack frame, and then return a pointer to it:

TEg* foo() - { - TEg s; - TEg* ps=&s - return ps; // !! error !! - } -

This pointer will not be valid for long, because the memory -will be re-used when the next function is called. You should never allow this -to happen. This error is so obvious that a compiler will trap it. But it can -occur in more subtle forms:

foo(CContainer* aContainer) - { - TEg s; - TEg* ps=&s - aContainer->iMember=ps; - } -

These cannot be trapped so easily.

-
Heap

Each thread also has a heap. You can allocate -and de-allocate objects on the heap at will, and refer to them by pointer. -The benefit of a heap is that the lifetime of an object is entirely within -your control. This power comes with responsibility: you must not forget to -de-allocate objects once you have finished with them, and you must not use -pointers to objects that have been de-allocated.

+ + + + + +C++ +and Machine ArchitectureThe C++ language, following its foundation in C, is close to the +machine architecture. This allows applications to be implemented efficiently, +but, especially for developers new to the language, presents some issues of +which you need to be aware. This topic reviews the basic language features +from this perspective, and discusses how the resulting issues are handled. +
Arithmetic types

An int is +usually implemented as the natural machine word size of the particular implementation. +This is 32 bits in most modern machines. It was 16 bits in older machines, +and in a few machines it may even be 64 bits.

Similarly, a pointer +(a void*, for instance) is usually implemented as a machine +word but, in some machines with special architectures, a pointer may be more +complex.

It is assumed that Symbian is implemented on a machine +with a 32-bit or greater machine word, and 32-bit pointers. The types TInt and TUint are typedefed onto the built-in int and unsigned int types, +and are guaranteed to be at least 32 bits.

When you need a specific +size, regardless of implementation, use a sized type. Several of these are +available:

+ + + +

TInt32, TUint32

+

32-bit signed and unsigned integer

In each case, the +representation is a 32-bit machine word which, in the ARM architecture, must +be aligned to a four-byte boundary. The compiler ensures that this is always +the case.

+
+ +

TInt8, TUint8, TText8

+

8-bit signed and unsigned integer, and 8-bit character

In +each case, the representation is an 8-bit byte, which has no specific alignment +requirements.

+
+ +

TInt16, TUint16, TText16

+

16-bit signed and unsigned integer, and 16-bit character

In +each case, the representation is a 16-bit halfword, which should be aligned +to a two-byte boundary.

+
+ +

TInt64, TUint64

+

64-bit signed and unsigned integer

These are typedefed +to appropriate built-in types for the compiler being used (long long, and +unsigned long long for ARM RVCT).

+
+ +

TReal, TReal64

+

Double-precision floating point, IEEE754 64-bit representation + This is the floating-point type recommended for general use.

You +are recommended to perform operations in integer arithmetic if possible (for +instance, most GUI calculations), and to use floating-point only when the +problem demands it (for instance, a spreadsheet application).

On +processors that have floating point hardware, the compiler generates host +instructions which use that hardware directly. On processors which don't have +a floating point unit, the compiler implements the calculations in software. +

+
+ +

TReal32

+

32-bit floating point

This is smaller and quicker, but +should only be used when space and/or time are at a true premium, as its precision +is unsatisfactory for many applications.

+
+ + +
+
Compound types

Apart from classes, C++ inherits +from C various other types of compounding.

A struct maps an area +of memory:

struct TEg + { + TInt iInt; // offset 0, 4 bytes + TText8 iText; // offset 4, 1 byte + // 3 wasted bytes + TReal iReal; // offset 8, 8 bytes + } // total length = 16 bytes + +

Structures are regarded as T types: that is they +may not own heap-allocated resources such as C type classes. +

An array contains many built-ins or other types

TInt a[32]; // 32 TInts, = 128 bytes +S b[3]; // 3 Ss, = 48 bytes

The main disadvantage of using +C++ arrays is that there is no automatic checking of index values. For this +reason, and to support more complex containers, C++ has evolved the Standard +Template Library (STL). Symbian does not use STL, but provides its own range +of efficient container classes, for fixed, dynamic, and associative arrays. +For details, see Dynamic +Arrays.

+
Pointers

A pointer is a memory address. If you can +take the address of an object, then you can refer to it by pointer:

S* ps; // pointer to an S +ps=&s // take address of existing S +

A pointer is a 32-bit machine word, and could point to anything.

+ +

The specifier is placed next to the type rather than the name.

There +is often a need to refer to memory as anything: for this, a void* pointer +is used in C++. In Symbian, a TAny* may be referred to instead. +A TAny* is a pointer to anything.

+
Strings

In C++, the basic string is an array of +characters:

char* hello="hello";

This statement +does two things: firstly, it sets aside six bytes of memory containing the +characters 'h', 'e', 'l', 'l', 'o', '\0'. Secondly, it sets the pointer hello +to contain the address of the first of those bytes.

+ +

Functions accessing the string rely on this address as its starting +point, and the terminating \0 to indicate its end. Functions +which manipulate the string must either deliberately not extend it, or must +have some cue as to the amount of memory reserved for the string (beyond the +trailing\0) so they know how much it can be extended. This +leads to an awkward programming style, and every C++ library provides a way +to manipulate strings more elegantly. The Symbian platform solution is descriptors: +these are introduced in Descriptors

+
Functions

Functions are a piece of code which can +be called and executed from anywhere else in a program. The stack is used +to pass parameters and to contain local variables. The stack is often augmented +by machine registers, especially in a register-rich processor such as the +ARM, so that memory is often not used. But, conceptually, there is a stack, +and for the purposes of this explanation it is convenient to consider the +stack as if it were implemented entirely in memory.

Parameters are +passed by copying or evaluating onto the called functions stack frame. It +is bad practice to pass large parameters, such as an entire struct, or, in +fact, anything beyond two machine words in size, because this involves excessive +copying. Instead, a pointer or a reference should be used to pass the address, +instead of the data itself.

In a multi-tasking system such as Symbian, +each thread has its own stack, which is a pre-allocated area of memory. Each +function then allocates its own frame from the stack on entry, and de-allocates +it on exit. The advantage of the stack mechanism is that allocation and de-allocation +are very rapid indeed— just a couple of instructions. Also, the lifetime of +any variable on the stack is very well defined: it is the lifetime of its +owning function, or, in fact, its owning block, since functions may have blocks +within them.

When a function returns, its stack memory is still there: +it is just not allocated. The stack memory will be re-used by the next function +that is called. A potential source of error is to allocate an object on a +functions stack frame, and then return a pointer to it:

TEg* foo() + { + TEg s; + TEg* ps=&s + return ps; // !! error !! + } +

This pointer will not be valid for long, because the memory +will be re-used when the next function is called. You should never allow this +to happen. This error is so obvious that a compiler will trap it. But it can +occur in more subtle forms:

foo(CContainer* aContainer) + { + TEg s; + TEg* ps=&s + aContainer->iMember=ps; + } +

These cannot be trapped so easily.

+
Heap

Each thread also has a heap. You can allocate +and de-allocate objects on the heap at will, and refer to them by pointer. +The benefit of a heap is that the lifetime of an object is entirely within +your control. This power comes with responsibility: you must not forget to +de-allocate objects once you have finished with them, and you must not use +pointers to objects that have been de-allocated.

\ No newline at end of file