\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#422: Don't Use stdarg.h/va\_list in Public API}
\date{January 02, 2013}
\author{Jan Nijtmans}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#422}&\textbf{Don't Use stdarg.h/va\_list in Public API}\\\hline
Author&

Jan Nijtmans \tipmail{nijtmans}{users.sf.net}
\\
Created&Wednesday, \(\text{2}^{\text{nd}}\) January 2013\\
Type&Project\\
Tcl Version&\(9.0\)\\
State&Draft\\
Vote&Pending\\
Version&\tipversion$Revision: 1.1 $\\
Keywords&Tcl, API removal, varargs\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes to remove all functions which use the \textit{va\_list} type from the public API, and it describes what extensions using this should do to make their extension portable on the mingw-w64 gcc compiler on the AMD64 platform.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

The use of \textit{va\_list} in public API has the problem that different compilers have a different implementation of the \textit{va\_list} structure. The implication of this is that extensions which are compiled with mingw-w64 for the AMD64 platform, and call any of those functions will fail with a MSVC-compiled Tcl core. The reverse fails as well. For a brief description about this problem, see: \url{http://www.bailopan.net/blog/?p=30.} See also an earlier discusion in the Tcl Core mailing list: \url{http://code.activestate.com/lists/tcl-core/10807/}

\section{Specification}

This TIP proposes to remove the following 4 functions from the public API
\begin{itemize}
\item{}
Tcl\_AppendResultVA
\item{}
Tcl\_AppendStringsToObjVA
\item{}
Tcl\_SetErrorCodeVA
\item{}
Tcl\_PanicVA
\end{itemize}

In addition, the inclusion of \tiplangle{}stdarg.h\tiprangle{} should move from tcl.h to tclInt.h, as no public Tcl header uses it any more.

\section{Compatibility}

Extensions using any of those functions will not compile and run in Tcl 9.0 any more. They should be rewritten to use the same functions without the VA parameter. This can be done as follows.

Before:
\begingroup\small\begin{verbatim}
int mypanic(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    Tcl_PanicVA(fmt, ap);
    va_end(ap);
}
\end{verbatim}
\endgroup

After:
\begingroup\small\begin{verbatim}
int mypanic(const char *fmt, ...) {
    va_list ap;
    char *arg1, *arg2, *arg3, *arg4;
    va_start(ap, fmt);
    arg1 = va_arg(argList, char *);
    arg2 = va_arg(argList, char *);
    arg3 = va_arg(argList, char *);
    arg4 = va_arg(argList, char *);
    va_end(ap);
    Tcl_Panic(fmt, arg1, arg2, arg3, arg4);
}
\end{verbatim}
\endgroup

The number of args used (4, in this example) should be chosen to be the maximum number of additional parameters that is used in any ``mypanic'' call. Since this function is only ever called from the extensions itself, this can be determined easily.

In addition, the extension must do its own inclusion of \tiplangle{}stdarg.h\tiprangle{}, as tcl.h doesn't do that any more.

Extensions rewritten this way, will continue to compile and function with Tcl 8.x as well. I am not aware of any extension which actually calls any of those VA functions.

\section{Reference Implementation}

A reference implementation is available in the \textbf{novem-remove-va} branch. [\url{https://core.tcl.tk/tcl/timeline?r=novem-remove-va}]

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
