Symbian3/SDK/Source/GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46.dita
changeset 7 51a74ef9ed63
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46.dita	Wed Mar 31 11:11:55 2010 +0100
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46" xml:lang="en"><title>Possible
+Problems</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>This section describes the possible problems that you may encounter when
+you develop applications or libraries on the Symbian platform
+based on Standard C++. These problems can occur in the following scenarios: </p>
+<ul>
+<li id="GUID-A3F0DCD7-CA38-5405-B01D-1E3B3F75B67D"><p><xref href="GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46.dita#GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46/GUID-39350E32-26C2-5440-B221-10EE693CCF18">Use of operator new</xref>  </p> </li>
+<li id="GUID-9B185254-36B9-58F7-888D-8198EAD77769"><p><xref href="GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46.dita#GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46/GUID-A85386B3-3E37-5303-8FBF-211551D5CB71">Use of one definition rule</xref>  </p> </li>
+<li id="GUID-01A440D6-7E35-5F4E-8E1E-F5877F3967F2"><p><xref href="GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46.dita#GUID-AF2CE612-F12E-5A18-81A5-C303992D2D46/GUID-6CE49D59-46BB-5145-B346-6FD3EA8BC011"> Standard C++ calling Symbian C++ functions </xref>  </p> </li>
+</ul>
+<section id="GUID-39350E32-26C2-5440-B221-10EE693CCF18"><title> Use of operator
+new()</title> <p>The function signatures of the global <codeph>operator new</codeph> on
+Symbian C++ and Standard C++ differ only in the exception specification. As
+per Standard C++, global <codeph>operator new</codeph> has the following signature: </p> <codeblock id="GUID-4369105F-C969-54E1-BBE5-C14ECA239F83" xml:space="preserve">void* operator new(std::size_t size) throw(std::bad_alloc);</codeblock> <p>While
+in Symbian C++, it is: </p> <codeblock id="GUID-9FCCB90D-3E2D-505B-8FC9-6E0FACAC09F3" xml:space="preserve">void* operator new(unsigned int aSize) throw();</codeblock> <p>Since the compiler name-mangles references to both these symbols as the same,
+it is possible (for the linker) to resolve a reference to one with the definition
+to the other. If such a combination is not identified at build time, the memory
+allocation may fail in the following cases: </p> <ol id="GUID-C6D4BDDD-B981-519C-9F2C-35DA294A23D9">
+<li id="GUID-FFD5DB62-462F-5A4A-BC51-DBE213B9BD0F"><p>If a reference to Symbian
+C++ <codeph>operator new</codeph> is resolved against the definition of Standard
+C++ <codeph>operator new</codeph>, then it throws an exception which may leave
+the <codeph>CleanupStack</codeph> in an unstable state. </p> </li>
+<li id="GUID-19A3119A-E882-5C17-9674-9B45D6307FFE"><p>If a reference to Standard
+C++ <codeph>operator new</codeph> is resolved against the definition of Symbian
+C++ <codeph>operator new</codeph>, then the <codeph>operator new</codeph> returns <b>NULL</b> (while
+an exception was expected). Since the return is not checked by the compiler,
+it may cause a bus error. </p> </li>
+</ol> <p>So, the declarations must be kept separate in the translation unit.
+In this case only one of them can appear in a translation unit. Also, since
+they have the same mangled names, they cannot appear in the same link unit. </p> </section>
+<section id="GUID-A85386B3-3E37-5303-8FBF-211551D5CB71"><title>Use of one
+definition rule</title> <p>As per Standard C++, one definition rule (ODR)
+says that there must be only one definition of a symbol in a program. But
+to be able to maintain a single definition in a program, symbol pre-emption
+must be possible. This functionality is not supported on the DLL model of
+the Symbian platform. </p> <p><b>Example</b> </p> <p>The following example
+illustrates the problem with the use of one definition rule: </p> <codeblock id="GUID-FB9FBAAD-8CB8-5EAB-BA25-18A92822CF8E" xml:space="preserve">//MySingleton.h
+template &lt;class T&gt;
+class MySingleton
+    {
+    public:
+    static T&amp; GetInstance()
+        {
+        static T * aT = NULL;
+        if (!aT) aT = new T;
+        return *aT;
+        }
+    };
+class X: public MySingleton&lt;X&gt;
+    {
+    public:
+    X(): iX(0) {};
+    int Prod()
+        {
+        return ++iX;
+        }
+    private:
+    int iX;
+    };</codeblock> <p> <b>Foo.cpp</b>  </p> <codeblock id="GUID-3AFCAE2C-8028-5813-BED1-889AD2909302" xml:space="preserve">#include &lt;MySingleton.h&gt;
+EXPORT_C int Foo()
+    {
+    return X::GetInstance().Prod();
+    }</codeblock> <p> <b>Bar.cpp</b>  </p> <codeblock id="GUID-6C00938A-2CD5-58D8-B937-6EE73C5BF483" xml:space="preserve">#include &lt;MySingleton.h&gt;
+EXPORT_C int Bar()
+    {
+    return X::GetInstance().Prod();
+    }</codeblock> <p>In a scenario where <filepath>Foo.cpp</filepath> is in <filepath>Foo.dll</filepath> and <filepath>Bar.cpp</filepath> is
+in <filepath>Bar.dll.</filepath> To call <codeph>Foo</codeph> and <codeph>Bar</codeph> from
+an application: </p> <codeblock id="GUID-E4A0FA6F-9792-5052-80B5-2372EB53FBFA" xml:space="preserve">int Baz()
+    {
+    return Foo() + Bar();
+    }
+int E32Main()
+    {
+    printf("%d\n", Baz());
+    }</codeblock> <p>This example must have displayed the output as <b>1,
+2</b>. But on the Symbian platform, it displays <b>1,1</b>. </p> <p>The problem
+here is, the Symbian platform's DLL model. In particular, the Symbian platform
+does not support symbol pre-emption. <codeph>static T * aT</codeph> gets allocated
+in each DLL in which <codeph>X::GetInstance</codeph> is invoked. Here the
+problem arises because the Symbian platform cannot redirect the references
+in distinct DLLs to a single unique location as required by the ODR. </p> </section>
+<section id="GUID-6CE49D59-46BB-5145-B346-6FD3EA8BC011"><title>Standard C++
+calling Symbian C++ functions</title> <p>The following example illustrates
+the nature of one of the problems associated with achieving <i>seamless</i> integration
+of Standard C++ with Symbian C++. Here <i>seamless</i> means: without the
+manual introduction of additional harness or barrier code to effect the integration. </p> <p> <codeph>SymbianCallerLC</codeph> calls
+two different functions: </p> <ul>
+<li id="GUID-CC89E765-AF86-5300-BB76-F84DCF9E3910"><p>one which expects standard
+C++ semantics (<codeph>CppCallee</codeph>), and </p> </li>
+<li id="GUID-2E9D21A4-8FD3-5DC9-A264-7E7FEA05F4A9"><p>another which expects
+the Symbian platform semantics (<codeph>GetAK1LC</codeph>). </p> </li>
+</ul> <p> <codeph>SymbianCallerLC</codeph> itself belongs to the Symbian C++
+world since it participates in the LC convention (it imposes a contract on
+its caller with respect to the object that it returns). </p> <codeblock id="GUID-D88FA0A6-1107-570D-B79A-30EA10E4AB0C" xml:space="preserve">K1 * SymbianCallerLC()
+    {
+    K1 * aK1 = GetAK1LC();
+    CppCallee(aK1);
+    return aK1;
+    }</codeblock> <p>The sole point of this function is to demonstrate that <i>stack
+depth</i> cannot be used as an implicit means to synchronize the cleanup stack
+with the control stack. It might be thought that recording <i>stack depth</i> at
+the point at which an object is pushed onto the cleanup stack can be used
+by the runtime to determine if the object should be <i>popped and destroyed</i> during
+a standard C++ <i>throw</i>. Such a belief would be erroneous. For example,
+a stack allocated object of sufficient size (<codeph>aArray</codeph> in this
+case). The <i>stack depth</i> when the object allocated by <codeph>K1::NewLC</codeph> is
+pushed on the cleanup stack is bound to be greater than the <i>stack depth</i> when
+the <codeph>try</codeph> statement is executed in <codeph>CppCallee</codeph>.
+From this example, therefore, that the <i>stack depth</i> at which an object
+was allocated (or rather pushed onto the cleanup stack) gives no indication
+of the ordering of various operations and can therefore not be used to determine
+the inclusion of one extent within another. </p> <codeblock id="GUID-4FD53631-1369-5833-B0C0-1FD4F3C28BFB" xml:space="preserve">K1 * GetAK1LC()
+    {
+    int aArray[100]; 
+    // stack frame for GetAK1LC has space for 100 ints - i.e. sp in this call to K1::NewLC 
+    // will be less than at the 'try' in CppCallee
+    return K1::NewLC(aArray);
+    }</codeblock> <p>In the current context the object returned by <codeph>GetAnotherK1LC</codeph> will
+be pushed on the cleanup stack when stack depth is less than it was in the
+earlier call to <codeph>GetAK1LC</codeph>, more evidence that stack depth
+cannot be used to determine ordering or extent inclusion. </p> <codeblock id="GUID-798CD3AA-0E08-5641-9FDA-DCE5224C7457" xml:space="preserve">K1 * GetAnotherK1LC()
+    {
+    return K1::NewLC();
+    }</codeblock> <p> <codeph> CppCallee(K1 * aK1)</codeph> is a <i>catcher</i> which
+calls <codeph>CppCallee(K1 * aK1, K1 aK2)</codeph> which can throw. It also
+calls <codeph>GetAnotherK1LC()</codeph> in the extent of the <codeph>try</codeph> statement.
+If <codeph>CppCallee(K1 * aK1, K1 aK2)</codeph> throws it might seem desirable
+that <codeph>anotherK1</codeph> must be cleaned up by the runtime as part
+of the throw. </p> <codeblock id="GUID-EAB8D25C-F8C4-5CF1-8AE4-5BEE7A877567" xml:space="preserve">void CppCallee(K1 * aK1)
+    {
+    try 
+        {
+        K1 * anotherK1 = NULL;
+        anotherK1 = GetAnotherK1LC();
+        CppCallee(aK1, anotherK1);
+        }
+    catch (...)
+        {
+        }
+    }</codeblock> </section>
+</conbody><related-links>
+<link href="GUID-D6BEAF0D-844D-51F4-8DB7-FB1D60E17FE3.dita"><linktext>Copyright
+Acknowledgments for Standard C++ (STLport)</linktext></link>
+<link href="GUID-F7FEB759-E64D-5B6D-9017-C5E982E4FC16.dita"><linktext>Standard
+C++ Library Overview</linktext></link>
+<link href="GUID-2CCD1748-9EDE-5383-9941-A3051E06F3E2.dita"><linktext>Standard
+C++ Support on the Symbian Platform</linktext></link>
+<link href="GUID-1ACD01D1-2055-581A-9478-2C0D7D1CF9E6.dita"><linktext>Use Cases
+for Writing Standard C++ Code</linktext></link>
+<link href="GUID-E331B72B-84AF-558A-9B8F-73E5E50B58C7.dita"><linktext>Building
+a Standard C++ Application or Library</linktext></link>
+<link href="GUID-D32E52C9-F05C-5F1E-8B49-243D555C353C.dita"><linktext>Known Issues</linktext>
+</link>
+<link href="GUID-5B3F5296-D6D0-5D25-8362-141DF5927E52.dita"><linktext>Troubleshooting</linktext>
+</link>
+</related-links></concept>
\ No newline at end of file