March 3, 2021
Hot Topics:

Advanced C++/CLI: Type Forwarding, Pointers, and Variable Argument Lists

  • By Nick Wienholt
  • Send Email »
  • More Articles »

Variable Argument Lists

The syntax for specifying a variable argument list in C++/CLI is much the same as the standard C/C++ equivalent. As a quick recap, a standard C++ variable argument list is specified using the ellipsis (...) syntax, and the function consuming the variable argument list iterates over the argument list using the CRT va_arg and va_start macos:

int max(int argCount, ...){
   va_list args;
   va_start(args, argCount);
   int retVal = va_arg(args, int);

   for (int ix = 1; ix < argCount; ++ix){
      int nextVal = va_arg(args, int);
      if (nextVal > retVal){
         retVal = nextVal;
   va_end(args);    //reset list
   return retVal;

int _tmain(int argc, _TCHAR* argv[])
   int maxVal = max(5, 2, 5, 3, 7, 1);
   return 0;

The standard C/C++ mechanism for variable argument lists lacks type safety and can result in stack corruption as the parameter count is passed into the variable-argument function with no checks on its validity, raising the prospect of an incorrect number of arguments popped off the call stack. These problems mean that a direct translation of the standard variable-argument mechanism is not suitable for C++/CLI, which has verifiable type safety as one of the language's requirements. In fact, the nature of standard C/C++ variable argument routines is so incompatible with the .NET runtime that the C++ compiler will generate native instructions for variable-argument list functions even if the /clr compiler switch is used.

The C++/CLI language attempts to offer familiar syntax to the C++ developer in situations where using standard C++ syntax doesn't end up causing unnecessary confusion. In some situations, introducing new syntax such as the object handle (^) to replace the pointer (*) was chosen to clearly differentiate the different concepts. With variable argument lists, the C++/CLI language designers chose to offer a slightly modified form of the standard syntax—the ellipsis is maintained, and type safety is introduced by adding a managed array signature after the ellipsis. Re-writing the earlier code sample as a C++/CLI equivalent, the result is:

using namespace System;
int max(...array<Int32>^ arr ) {
   int retVal = int::MinValue;
   for (int ix = 0; ix < arr->Length; ++ix){
      if (arr[ix] > retVal){
         retVal = arr[ix];

   return retVal;

int _tmain(int argc, _TCHAR* argv[])
   int maxVal = max(2, 5, 3, 7, 1);
   return 0;

The C++/CLI implementation of the max function is actually easier to author and call—the ability to program against an array rather than the va_* macros makes for a simpler implementation, and on the calling side, the removal of the need to specify the parameter count makes calling the max function simpler.

Other than the slightly different syntax of specifying an array after the ellipsis, the C++/CLI variable argument list experience is much the same as the standard C++ ancestor—only one variable argument list can be specified for a particular function, and it must be the last parameter in the function's parameter list. C++/CLI variable argument lists can be used in applications compiled with /clr:safe, and can be used seamlessly from other managed languages.


The C++/CLI language is designed to allow a C++ developer to use the familiar syntax of C++ to target the .NET runtime. By providing features that look and feel like 'real' C++ but map seamlessly to the behavior of .NET, the C++ developer gets the best of both worlds. C++/CLI variable argument lists and the pointer templates deliver a syntax and feel very close to equivalents in the native world, yet are fully compatible with the requirements of the .NET runtime.

Type forwarding is a compatibility feature that allows developers creating large class libraries to refactor which assemblies that types live in without breaking existing clients. Type forwarding was originally developed to support internal Microsoft teams working on the .NET Framework Libraries in .NET 2, but was exposed in .NET and C++/CLI to allow the same flexibility for third-party class library developers.

About the Author

Nick Wienholt is an independent Windows and .NET consultant based in Sydney. He is the author of Maximizing .NET Performance and co-author of A Programmers Introduction to C# 2.0 from Apress, and specialises in system-level software architecture and development, with a particular focus of performance, security, interoperability, and debugging.

Nick is a keen and active participant in the .NET community. He is the co-founder of the Sydney Deep .NET User group and writes technical articles for Australian Developer Journal, ZDNet, Pinnacle Publishing, CodeGuru, MSDN Magazine (Australia and New Zealand Edition) and the Microsoft Developer Network. An archive of Nick's SDNUG presentations, articles, and .NET blog is available at www.dotnetperformance.com. In recognition of his work in the .NET area, he was awarded the Microsoft Most Valued Professional Award from 2002 through 2007.

Page 2 of 2

This article was originally published on December 17, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date