Symbian3/SDK/Source/GUID-8675AC01-E2D8-425C-899F-12BE99345AA9.dita
changeset 0 89d6a7a84779
equal deleted inserted replaced
-1:000000000000 0:89d6a7a84779
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-8675AC01-E2D8-425C-899F-12BE99345AA9" xml:lang="en"><title>C++
       
    13 and Machine Architecture</title><shortdesc>The C++ language, following its foundation in C, is close to the
       
    14 machine architecture. This allows applications to be implemented efficiently,
       
    15 but, especially for developers new to the language, presents some issues of
       
    16 which you need to be aware. This topic reviews the basic language features
       
    17 from this perspective, and discusses how the resulting issues are handled.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    18 <section>       <title>Arithmetic types</title>       <p>An <codeph>int</codeph> is
       
    19 usually implemented as the natural machine word size of the particular implementation.
       
    20 This is 32 bits in most modern machines. It was 16 bits in older machines,
       
    21 and in a few machines it may even be 64 bits.     </p><p>Similarly, a pointer
       
    22 (a <codeph>void*</codeph>, for instance) is usually implemented as a machine
       
    23 word but, in some machines with special architectures, a pointer may be more
       
    24 complex.     </p><p>It is assumed that Symbian is implemented on a machine
       
    25 with a 32-bit or greater machine word, and 32-bit pointers. The types <codeph>TInt</codeph> and <codeph>TUint</codeph> are<codeph> typedefed</codeph> onto the built-in <codeph>int</codeph> and <codeph>unsigned int</codeph> types,
       
    26 and are guaranteed to be at least 32 bits.     </p><p>When you need a specific
       
    27 size, regardless of implementation, use a sized type. Several of these are
       
    28 available: </p><table id="GUID-8E1CEF20-AF41-4980-AA56-5CBF2B7F6A9E">
       
    29 <tgroup cols="2"><colspec colname="col1"/><colspec colname="col2"/>
       
    30 <tbody>
       
    31 <row>
       
    32 <entry><p><codeph>TInt32</codeph>, <codeph>TUint32</codeph> </p> </entry>
       
    33 <entry><p>32-bit signed and unsigned integer</p>    <p> In each case, the
       
    34 representation is a 32-bit machine word which, in the ARM architecture, must
       
    35 be aligned to a four-byte boundary. The compiler ensures that this is always
       
    36 the case.</p>  </entry>
       
    37 </row>
       
    38 <row>
       
    39 <entry><p><codeph>TInt8</codeph>, <codeph>TUint8</codeph>, <codeph>TText8</codeph></p>  </entry>
       
    40 <entry><p>8-bit signed and unsigned integer, and 8-bit character     </p><p>In
       
    41 each case, the representation is an 8-bit byte, which has no specific alignment
       
    42 requirements.  </p></entry>
       
    43 </row>
       
    44 <row>
       
    45 <entry><p><codeph>TInt16</codeph>, <codeph>TUint16</codeph>, <codeph>TText16</codeph> </p></entry>
       
    46 <entry><p>16-bit signed and unsigned integer, and 16-bit character     </p><p>In
       
    47 each case, the representation is a 16-bit halfword, which should be aligned
       
    48 to a two-byte boundary.  </p></entry>
       
    49 </row>
       
    50 <row>
       
    51 <entry><p><codeph>TInt64</codeph>, <codeph>TUint64</codeph>  </p></entry>
       
    52 <entry><p>64-bit signed and unsigned integer     </p><p>These are typedefed
       
    53 to appropriate built-in types for the compiler being used (long long, and
       
    54 unsigned long long for ARM RVCT).  </p></entry>
       
    55 </row>
       
    56 <row>
       
    57 <entry><p><codeph>TReal</codeph>, <codeph>TReal64</codeph> </p></entry>
       
    58 <entry><p>Double-precision floating point, IEEE754 64-bit representation 
       
    59    This is the floating-point type recommended for general use.     </p><p>You
       
    60 are recommended to perform operations in integer arithmetic if possible (for
       
    61 instance, most GUI calculations), and to use floating-point only when the
       
    62 problem demands it (for instance, a spreadsheet application).     </p><p>On
       
    63 processors that have floating point hardware, the compiler generates host
       
    64 instructions which use that hardware directly. On processors which don't have
       
    65 a floating point unit, the compiler implements the calculations in software.
       
    66  </p></entry>
       
    67 </row>
       
    68 <row>
       
    69 <entry><p><codeph>TReal32</codeph> </p></entry>
       
    70 <entry><p>32-bit floating point     </p><p>This is smaller and quicker, but
       
    71 should only be used when space and/or time are at a true premium, as its precision
       
    72 is unsatisfactory for many applications.  </p></entry>
       
    73 </row>
       
    74 </tbody>
       
    75 </tgroup>
       
    76 </table>     </section>
       
    77 <section><title>Compound types</title><p>Apart from classes, C++ inherits
       
    78 from C various other types of compounding.     </p><p>A struct maps an area
       
    79 of memory: </p><codeblock xml:space="preserve">struct TEg
       
    80     {
       
    81     TInt iInt; // offset 0, 4 bytes
       
    82     TText8 iText; // offset 4, 1 byte
       
    83         // 3 wasted bytes
       
    84     TReal iReal; // offset 8, 8 bytes
       
    85     } // total length = 16 bytes</codeblock><fig id="GUID-70477651-EC14-4321-ACA5-79CEE4AEC69E">
       
    86 <image href="GUID-7E801A44-4509-5AC0-88D5-7DEA1AF7969D_d0e2078_href.png" placement="inline"/>
       
    87 </fig><p>Structures are regarded as <codeph>T</codeph> types: that is they
       
    88 may not own heap-allocated resources such as <codeph>C</codeph> type classes.
       
    89     </p><p>An array contains many built-ins or other types </p><codeblock xml:space="preserve">TInt a[32]; // 32 TInts, = 128 bytes  
       
    90 S b[3]; // 3 Ss, = 48 bytes </codeblock><p>The main disadvantage of using
       
    91 C++ arrays is that there is no automatic checking of index values. For this
       
    92 reason, and to support more complex containers, C++ has evolved the Standard
       
    93 Template Library (STL). Symbian OS does not use STL, but provides its own
       
    94 range of efficient container classes, for fixed, dynamic, and associative
       
    95 arrays. For details, see <xref href="GUID-2F64B579-73D3-548A-9104-16483AF77BCB.dita">Dynamic
       
    96 Arrays</xref>. </p></section>
       
    97 <section><title>Pointers</title><p>A pointer is a memory address. If you can
       
    98 take the address of an object, then you can refer to it by pointer:</p><codeblock xml:space="preserve">S* ps; // pointer to an S
       
    99 ps=&amp;s // take address of existing S
       
   100 </codeblock><p>A pointer is a 32-bit machine word, and could point to anything.</p><fig id="GUID-D33AB198-0B62-4391-B86D-088595AE6B8B">
       
   101 <image href="GUID-045F3455-2B5A-5B20-ABCE-ED202DC5078A_d0e2109_href.png" placement="inline"/>
       
   102 </fig><p>The specifier is placed next to the type rather than the name.   </p><p>There
       
   103 is often a need to refer to memory as anything: for this, a <codeph>void*</codeph> pointer
       
   104 is used in C++. In Symbian, a <codeph>TAny*</codeph> may be referred to instead.
       
   105 A <codeph>TAny*</codeph> is a pointer to anything. </p></section>
       
   106 <section><title>Strings</title><p>In C++, the basic string is an array of
       
   107 characters:</p><codeblock xml:space="preserve">char* hello="hello";</codeblock><p>This statement
       
   108 does two things: firstly, it sets aside six bytes of memory containing the
       
   109 characters 'h', 'e', 'l', 'l', 'o', '\0'. Secondly, it sets the pointer hello
       
   110 to contain the address of the first of those bytes. </p><fig id="GUID-08C1AF40-8D93-414E-B103-1E57AB17480F">
       
   111 <image href="GUID-512D0DA7-0BC2-534F-9233-11F46D285CA6_d0e2138_href.png" placement="inline"/>
       
   112 </fig><p>Functions accessing the string rely on this address as its starting
       
   113 point, and the terminating <codeph>\0</codeph> to indicate its end. Functions
       
   114 which manipulate the string must either deliberately not extend it, or must
       
   115 have some cue as to the amount of memory reserved for the string (beyond the
       
   116 trailing<codeph>\0</codeph>) so they know how much it can be extended. This
       
   117 leads to an awkward programming style, and every C++ library provides a way
       
   118 to manipulate strings more elegantly. The Symbian platform solution is <i>descriptors</i>:
       
   119 these are introduced in <xref href="GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230.dita">Descriptors</xref></p></section>
       
   120 <section><title>Functions</title><p>Functions are a piece of code which can
       
   121 be called and executed from anywhere else in a program. The stack is used
       
   122 to pass parameters and to contain local variables. The stack is often augmented
       
   123 by machine registers, especially in a register-rich processor such as the
       
   124 ARM, so that memory is often not used. But, conceptually, there is a stack,
       
   125 and for the purposes of this explanation it is convenient to consider the
       
   126 stack as if it were implemented entirely in memory.   </p><p>Parameters are
       
   127 passed by copying or evaluating onto the called functions stack frame. It
       
   128 is bad practice to pass large parameters, such as an entire struct, or, in
       
   129 fact, anything beyond two machine words in size, because this involves excessive
       
   130 copying. Instead, a pointer or a reference should be used to pass the address,
       
   131 instead of the data itself.   </p><p>In a multi-tasking system such as Symbian,
       
   132 each thread has its own stack, which is a pre-allocated area of memory. Each
       
   133 function then allocates its own frame from the stack on entry, and de-allocates
       
   134 it on exit. The advantage of the stack mechanism is that allocation and de-allocation
       
   135 are very rapid indeed— just a couple of instructions. Also, the lifetime of
       
   136 any variable on the stack is very well defined: it is the lifetime of its
       
   137 owning function, or, in fact, its owning block, since functions may have blocks
       
   138 within them.   </p><p>When a function returns, its stack memory is still there:
       
   139 it is just not allocated. The stack memory will be re-used by the next function
       
   140 that is called. A potential source of error is to allocate an object on a
       
   141 functions stack frame, and then return a pointer to it: </p><codeblock xml:space="preserve">TEg* foo()
       
   142     {
       
   143     TEg s;
       
   144     TEg* ps=&amp;s
       
   145     return ps; // !! error !!
       
   146     }
       
   147 </codeblock><p>This pointer will not be valid for long, because the memory
       
   148 will be re-used when the next function is called. You should never allow this
       
   149 to happen. This error is so obvious that a compiler will trap it. But it can
       
   150 occur in more subtle forms: </p><codeblock xml:space="preserve">foo(CContainer* aContainer)
       
   151     {
       
   152     TEg s;
       
   153     TEg* ps=&amp;s
       
   154     aContainer-&gt;iMember=ps;
       
   155     }
       
   156 </codeblock><p>These cannot be trapped so easily. </p></section>
       
   157 <section><title>Heap</title><p>Each thread also has a heap. You can allocate
       
   158 and de-allocate objects on the heap at will, and refer to them by pointer.
       
   159 The benefit of a heap is that the lifetime of an object is entirely within
       
   160 your control. This power comes with responsibility: you must not forget to
       
   161 de-allocate objects once you have finished with them, and you must not use
       
   162 pointers to objects that have been de-allocated. </p></section>
       
   163 </conbody></concept>