<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Sun May 26 04:57:53 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='340'>
<header><title>Const Qualification of Tcl_SetResult&apos;s Argument</title><author address="mailto:nijtmans@users.sourceforge.net">Jan Nijtmans</author><status type='project' state='draft' tclversion="8.7" vote='prior'>$Revision: 1.7 $</status><history></history><created day='14' month='nov' year='2008' /><keyword>Tcl_SetResult</keyword></header>
<abstract>As a follow-up of <tipref type="text" tip="27"/>, in Tcl 8.6 and Tk 8.6 much work has been done to clean up the remaining places where pointers were not <emph style="italic">const</emph> qualified. The question is, how can we prevent that in the future similar &quot;mistakes&quot; are made. The gcc compiler warning <emph style="italic">-Wwrite-strings</emph> helps in that, therefore this TIP proposes to add that to the CFLAGS_WARNING flag in Tcl and Tk when using gcc. But for this flag to be introduced, all warnings will have to be eliminated. In the HEAD, this is done already, except for one function: <emph style="bold">Tcl_SetResult</emph>. This function is explicitely mentioned in <tipref type="text" tip="27"/> not to be modified, because it cannot be handled without unsafe casting. This TIP proposes to deprecate <emph style="bold">Tcl_SetResult</emph> in full, and provide a new macro <emph style="bold">Tcl_SetStringResult</emph> in its place.</abstract>
<body><section title="Rationale">
<para>The gcc manual mentions for the flag -Wwrite-strings:</para>
<quote>When compiling C, give string constants the type <emph style="italic">const char[length]</emph> so that copying the address of one into a non-<emph style="italic">const char *</emph> pointer will get a warning .... These warnings will help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using const in declarations and prototypes. Otherwise, it will just be a nuisance; this is why we did not make -Wall request these warnings.</quote>
<para>Now that all Tcl and Tk API&apos;s are modified to be very careful about using const, this opens the way to add <emph style="italic">-Wwrite-strings</emph> to CFLAGS_WARNING when building with gcc. Other extensions can start to do the same, if they want to find out about this type of potential problem.</para>
<para>When considering the elimination of the warning when using <emph style="italic">&apos;Tcl_SetResult</emph>, I originally see two alternatives:</para>
<itemize><item.i><para>Change the implementation such that <emph style="bold">Tcl_SetResult</emph>(<emph style="italic">i, s, f</emph>) does the same as <emph style="bold">Tcl_SetObjResult</emph>(<emph style="italic">i</emph>, <emph style="bold">Tcl_NewStringObj</emph>(<emph style="italic">s</emph>, -1)), ignoring the last parameter.</para><para>This can be done without an unsafe type cast, but it has the disadvantage that after a (modified) <emph style="bold">Tcl_SetResult</emph> call the result is no longer available in interp-&gt;result. Older extensions might expect that, those will be silently broken. A the moment, serveral tests fail when doing this, because in various places of the Tcl core there are hack which still support older extensions which still use interp-&gt;result directly. It&apos;s a little short before Tcl 8.6 to do it now, but it should certainly be considered for the future.</para></item.i><item.i><para>The solution that originally was proposed in this TIP was to leave the <emph style="bold">Tcl_SetResult</emph> implementation as it is, only add a single type cast to prevent a gcc warning.</para><para>This violates the <tipref type="text" tip="27"/> conditions, but is in fact not more dangerous than the current situation. It is only dangerous, when the Tcl_SetResult call has another value than TCL_STATIC or TCL_VOLATILE as last argument</para></item.i><item.i><para>The final proposal is a new macro <emph style="bold">Tcl_SetStringResult</emph> that takes over the function of <emph style="bold">Tcl_SetResult</emph>. The function <emph style="bold">Tcl_SetResult</emph> will be deprecated in full.</para></item.i></itemize>
<para>There has been a discussion stating that changing the <emph style="bold">Tcl_SetResult</emph> signature is wrong, because <emph style="bold">Tcl_SetResult</emph> cannot be made const-correct.</para>
<para>Most <emph style="bold">Tcl_SetResult</emph> calls use TCL_STATIC or TCL_VOLATILE as last argument. In this case, the second argument is expected to be a const. The macro <emph style="bold">Tcl_SetStringResult</emph> takes care of that, since it is implemented in terms of <emph style="bold">Tcl_SetObjResult</emph> and <emph style="bold">Tcl_NewStringObj</emph>.</para>
<para>Very few <emph style="bold">Tcl_SetResult</emph> calls have some other value as last argument, most likely TCL_DYNAMIC. This TIP proposes to deprecate <emph style="bold">Tcl_SetResult</emph> for all values of freeProc. If the value is TCL_STATIC or TCL_VOLATILE, there is a new macro <emph style="bold">Tcl_SetStringResult</emph> which can be used in stead. For other values the call can be replaced with <emph style="bold">Tcl_SetStringResult</emph> as well, but then the caller is responsible to free the memory after the <emph style="bold">Tcl_SetStringResult</emph> call.</para>
<para>It turns out that Tcl had only 4 deprecated (as defined by this TIP) <emph style="bold">Tcl_SetResult</emph> calls, one of them was wrong [Bug 2308236], two of them were in tclTest.c meant to test the <emph style="bold">Tcl_SetResult</emph> function itself. Tk had only 5 such calls. All those calls have been modified now. Tcl and Tk now only calls <emph style="bold">Tcl_SetResult</emph> with either TCL_STATIC or TCL_VOLATILE</para>
<para>This proposal does not have the &quot;forward compatibility&quot; problem, that extensions using <emph style="bold">Tcl_SetStringResult</emph> compiled. it is even possible for extensions to use <emph style="bold">Tcl_SetStringResult</emph> with Tcl 8.5 and before:</para>
<verbatim><vline encoding='base64'>ICNpZm5kZWY=</vline><vline encoding='base64'>ICMgICBkZWZpbmUgVGNsX1NldFN0cmluZ1Jlc3VsdChpLHMpIFw=</vline><vline encoding='base64'>ICAgICBUY2xfU2V0T2JqUmVzdWx0KGksIFRjbF9OZXdTdHJpbmdPYmoocywgLTEpKQ==</vline><vline encoding='base64'>ICNlbmRpZg==</vline></verbatim>
</section>
<section title="Reference Implementation">
<para>A new patch will be available in issue #2315890 [<url ref="http://sourceforge.net/support/tracker.php/?aid=2315890"/>].</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
