Sophie

Sophie

distrib > Fedora > 18 > x86_64 > by-pkgid > ff187cb994c94c614ecc64c5a8528b1b > files > 7455

qt-doc-4.8.5-10.fc18.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- symbian-exceptionsafety.qdoc -->
  <title>Qt 4.8: Exception Safety with Symbian</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <div class="breadcrumb toolblock">
            <ul>
              <li class="first"><a href="index.html">Home</a></li>
              <!--  Breadcrumbs go here -->
<li>Exception Safety with Symbian</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#what-the-problem-is">What the problem is</a></li>
<li class="level1"><a href="#qt-calls-to-symbian">Qt calls to Symbian</a></li>
<li class="level2"><a href="#be-careful-with-new-and-cbase">Be careful with new and CBase</a></li>
<li class="level1"><a href="#qt-called-from-symbian">Qt called from Symbian</a></li>
<li class="level1"><a href="#common-sense-things">Common sense things</a></li>
<li class="level1"><a href="#advanced-technique">Advanced technique</a></li>
</ul>
</div>
<h1 class="title">Exception Safety with Symbian</h1>
<span class="subtitle"></span>
<!-- $$$symbianexceptionsafety.html-description -->
<div class="descr"> <a name="details"></a>
<p>The following sections describe how Qt code can interoperate with Symbian's exception safety system.</p>
<a name="what-the-problem-is"></a>
<h2>What the problem is</h2>
<p>Qt and Symbian have different exception systems. Qt works with standard C++ exceptions, whereas Symbian has its TRAP/Leave/CleanupStack system. So, what would happen if you mix the two systems? It could go wrong in a number of ways.</p>
<p>Clean-up ordering would be different between the two. When Symbian code leaves, the clean-up stack is cleaned up before anything else happens. After that, the objects on the call stack would be cleaned up as with a normal exception. So if there are any dependencies between stack-based and objects owned by the clean-up stack, there could be problems due to this ordering.</p>
<p>Symbian's <tt>XLeaveException</tt>, which is used when Symbian implements leaves as exceptions, is not derived from <tt>std::exception</tt>, so would not be caught in Qt catch statements designed to catch <tt>std::exception</tt>.</p>
<p>Qt's and standard C++'s <tt>std::exception</tt> derived exceptions result in program termination if they fall back to a Symbian TRAP.</p>
<p>These problems can be solved with barrier macros and helper functions that will translate between the two exception systems. Use them, in Qt code, whenever calling into or being called from Symbian code.</p>
<a name="qt-calls-to-symbian"></a>
<h2>Qt calls to Symbian</h2>
<p>When calling Symbian leaving functions from Qt code, we want to translate Symbian leaves to standard C++ exceptions. The following help is provided:</p>
<ul>
<li><a href="qtglobal.html#qt_symbian_throwIfError">qt_symbian_throwIfError</a>() takes a Symbian error code and throws an appropriate exception to represent it. This will do nothing if the error code is not in fact an error. The function is equivalent to Symbian's <tt>User::LeaveIfError</tt>.</li>
<li><a href="qtglobal.html#q_check_ptrx">q_check_ptr</a>() takes a pointer and throws a std::bad_alloc exception if it is 0, otherwise the pointer is returned. This can be used to check the success of a non-throwing allocation, eg from <tt>malloc()</tt>. The function is equivalent to Symbian's <tt>User::LeaveIfNull</tt>.</li>
<li><a href="qtglobal.html#QT_TRAP_THROWING">QT_TRAP_THROWING</a>() takes a Symbian leaving code fragment f and runs it under a trap harness converting any resulting error into an exception.</li>
<li><tt>TRAP</tt> and <tt>TRAPD</tt> from the Symbian libraries can be used to convert leaves to error codes.</li>
</ul>
<pre class="cpp"> HBufC<span class="operator">*</span> buf<span class="operator">=</span><span class="number">0</span>;
 <span class="comment">// this will throw a std::bad_alloc because we've asked for too much memory</span>
 <a href="qtglobal.html#QT_TRAP_THROWING">QT_TRAP_THROWING</a>(buf <span class="operator">=</span> HBufC<span class="operator">::</span>NewL(<span class="number">100000000</span>));

 _LIT(KStr<span class="operator">,</span><span class="string">&quot;abc&quot;</span>);
 TInt pos <span class="operator">=</span> KStr()<span class="operator">.</span>Locate(<span class="char">'c'</span>);
 <span class="comment">// pos is a good value, &gt;= 0, so no exception is thrown</span>
 <a href="qtglobal.html#qt_symbian_throwIfError">qt_symbian_throwIfError</a>(pos);

 pos <span class="operator">=</span> KStr()<span class="operator">.</span>Locate(<span class="char">'d'</span>);
 <span class="comment">// pos == KErrNotFound, so this throws an exception</span>
 <a href="qtglobal.html#qt_symbian_throwIfError">qt_symbian_throwIfError</a>(pos);

 <span class="comment">// we are asking for a lot of memory, HBufC::New may return NULL, so check it</span>
 HBufC <span class="operator">*</span>buffer <span class="operator">=</span> <a href="qtglobal.html#q_check_ptrx">q_check_ptr</a>(HBufC<span class="operator">::</span>New(<span class="number">1000000</span>));</pre>
<a name="be-careful-with-new-and-cbase"></a>
<h3>Be careful with new and CBase</h3>
<p>When writing Qt code, <tt>new</tt> will normally throw a <tt>std::bad_alloc</tt> if the allocation fails. However this may not happen if the object being created has its own <tt>operator new</tt>. For example, CBase and derived classes have their own <tt>operator new</tt> which returns 0 and the <tt>new(ELeave)</tt> overload for a leaving <tt>operator new</tt>, neither of which does what we want. When using 2-phase construction of CBase derived objects, use <tt>new</tt> and <a href="qtglobal.html#q_check_ptrx">q_check_ptr</a>().</p>
<p>For example, if you have code like</p>
<pre class="cpp"> CFbsBitmap* fbsBitmap = new(ELeave) CFbsBitmap;</pre>
<p>you can rewrite it as</p>
<pre class="cpp"> CFbsBitmap<span class="operator">*</span> fbsBitmap <span class="operator">=</span> <a href="qtglobal.html#q_check_ptrx">q_check_ptr</a>(<span class="keyword">new</span> CFbsBitmap);</pre>
<a name="qt-called-from-symbian"></a>
<h2>Qt called from Symbian</h2>
<p>When Qt code is called from Symbian, we want to translate standard C++ exceptions to Symbian leaves or error codes. The following help is provided:</p>
<ul>
<li><a href="qtglobal.html#qt_symbian_exception2Error">qt_symbian_exception2Error</a>() - this takes a standard exception and gives an appropriate Symbian error code. If no mapping is known for the exception type, <tt>KErrGeneral</tt> is returned.</li>
<li><a href="qtglobal.html#qt_symbian_exception2LeaveL">qt_symbian_exception2LeaveL</a>() - this takes a standard exception and generates an appropriate Symbian leave.</li>
<li><a href="qtglobal.html#QT_TRYCATCH_ERROR">QT_TRYCATCH_ERROR</a>() - this macro takes the standard C++ code fragment <tt>f</tt>, catches any std::exceptions thrown from it, and sets err to the corresponding Symbian error code. err is set to <tt>KErrNone</tt> otherwise.</li>
<li><a href="qtglobal.html#QT_TRYCATCH_LEAVING">QT_TRYCATCH_LEAVING</a>() - this macro takes the standard C++ code fragment <tt>f</tt>, catches any std::exceptions thrown from it, and throws a corresponding Symbian leave.</li>
</ul>
<pre class="cpp"> TInt DoTickL() <span class="comment">// called from an active object RunL, ie Symbian leaves expected</span>
     {
     <span class="comment">// without the translation to Symbian Leave, we get a USER:0 panic</span>
     QT_TRYCATCH_LEAVING({
         <span class="type">int</span><span class="operator">*</span> x <span class="operator">=</span> <span class="keyword">new</span> <span class="type">int</span><span class="operator">[</span><span class="number">100000000</span><span class="operator">]</span>;            <span class="comment">// compiled as Qt code, will throw std::bad_alloc</span>
         <span class="keyword">delete</span> <span class="operator">[</span><span class="operator">]</span> x;
     });
     <span class="keyword">return</span> <span class="number">0</span>;
     }</pre>
<a name="common-sense-things"></a>
<h2>Common sense things</h2>
<p>Try to minimise the interleaving of Symbian and Qt code, every switch requires a barrier. Grouping the code styles in different blocks will minimise the problems. For instance, examine the following code.</p>
<pre class="cpp"> <span class="number">1.</span>    TRAPD(err<span class="operator">,</span> m_playUtility <span class="operator">=</span> CMdaAudioPlayerUtility<span class="operator">::</span>NewL(<span class="operator">*</span><span class="keyword">this</span>);
 <span class="number">2.</span>               <span class="type"><a href="qstring.html">QString</a></span> filepath <span class="operator">=</span> <span class="type"><a href="qfileinfo.html">QFileInfo</a></span>( m_sound<span class="operator">-</span><span class="operator">&gt;</span>fileName() )<span class="operator">.</span>absoluteFilePath();
 <span class="number">3.</span>               filepath <span class="operator">=</span> <span class="type"><a href="qdir.html">QDir</a></span><span class="operator">::</span>toNativeSeparators(filepath);
 <span class="number">4.</span>               m_playUtility<span class="operator">-</span><span class="operator">&gt;</span>OpenFileL(qt_QString2TPtrC(filepath)));</pre>
<p>Line 1 starts a Symbian leave handling block, which is good because it also uses a Symbian leave generating function.</p>
<p>Line 2 creates a <a href="qstring.html">QString</a>, uses <a href="qfileinfo.html">QFileInfo</a> and various member functions. These could all throw exceptions, which is not good inside a <tt>TRAP</tt> block.</p>
<p>Line 3 is unclear as to whether it might throw an exception, but since it's dealing with strings it probably does, again bad.</p>
<p>Line 4 is tricky, it calls a leaving function which is ok within a <tt>TRAP</tt>, but it also uses a helper function to convert string types. In this case the helper function may cause an unwelcome exception.</p>
<p>We could rewrite this with nested exception translations, but it's much easier to refactor it.</p>
<pre class="cpp"> <span class="type"><a href="qstring.html">QString</a></span> filepath <span class="operator">=</span> <span class="type"><a href="qfileinfo.html">QFileInfo</a></span>( m_sound<span class="operator">-</span><span class="operator">&gt;</span>fileName() )<span class="operator">.</span>absoluteFilePath();
 filepath <span class="operator">=</span> <span class="type"><a href="qdir.html">QDir</a></span><span class="operator">::</span>toNativeSeparators(filepath);
 TPtrC filepathPtr(qt_QString2TPtrC(filepath));
 TRAPD(err<span class="operator">,</span> m_playUtility <span class="operator">=</span> CMdaAudioPlayerUtility<span class="operator">::</span>NewL(<span class="operator">*</span><span class="keyword">this</span>);
            m_playUtility<span class="operator">-</span><span class="operator">&gt;</span>OpenFileL(filepathPtr));</pre>
<p>Now the exception generating functions are separated from the leaving functions.</p>
<a name="advanced-technique"></a>
<h2>Advanced technique</h2>
<p>When using Symbian APIs in Qt code, you may find that Symbian leaving code and Qt exception throwing code are just too mixed up to have them interoperate through barriers. In some circumstances you can allow code to both leave and throw exceptions. But you must be aware of the following issues:</p>
<ul>
<li>Depending on whether a leave or exception is thrown, or a normal exit happens, the cleanup order will vary. If the code leaves, cleanup stack cleanup will happen first. On an exception however, cleanup stack cleanup will happen last.</li>
<li>There must not be any destructor dependencies between different code styles. That is, you must not have symbian objects using Qt objects in their destructors, and vice versa. This is because the cleanup order varies, and may result in objects being used after they are deleted.</li>
<li>The cleanup stack must not refer to any stack based object. For instance, in Symbian you may use <tt>CleanupClosePushL()</tt> to push stack based R-classes onto the cleanup stack. However if the stack has unwound due to an exception before the cleanup stack cleanup happens, stack based objects will now be invalid. Instead of using the cleanup stack, consider Symbian's new <tt>LManagedHandle&lt;&gt;</tt> (or a custom cleanup object) to tie R-class cleanup to the stack.</li>
<li>Mixed throwing code must be called within both a TRAP and a try/catch harness. Standard exceptions must not propagate to the TRAP and cleanup stack cleanup will only happen if a leave is thrown, so the correct pattern is either <tt>TRAPD(err, QT_TRYCATCH_LEAVING( f ));</tt> or <tt>QT_TRAP_THROWING( QT_TRYCATCH_LEAVING( f ));</tt>, depending if you want an error code or exception as a result.</li>
</ul>
</div>
<!-- @@@symbianexceptionsafety.html -->
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2013 Digia Plc and/or its
      subsidiaries. Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Digia, Qt and their respective logos are trademarks of Digia Plc 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
  </div>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>