Variable Length Arguments in C++, Java, and PHP

Normally in software development we define methods with a given number of parameters (and their type in some languages). Quite often however we want to be able to deal with different numbers of arguments and there are two widely used approaches; different methods and default parameters.

Different methods relies on the concept that the call to function is matched not just on the name of the method but also the count (and type if applicable) of the parameters. So if we wanted a method that could accept one or two integers in C++ we could define two methods:

void SomeFunction(int);
void SomeFunction(int, int);

So if we called SomeFunction(1) the first would be used, SomeFunction(1,2) would use the second.

Default parameters allows us to define some of the parameters as optional and their default values if not passed so the definition:

void SomeMethod(int a, int b=0);

Would accept one or two integer parameters. SomeMethod(1,2) would have a=1 and b=2 whereas SomeMethod(1) would use the default value and so b=0.

This is all very good and highly useful in a variety of situations but suppose you wanted to handle any number of parameters, from a very small set (or zero) to a large number. Using either of these techniques would require a lot of additional coding, creating a method for each length or the longest set of default parameters imaginable.

This is where the concept of variable length arguments for a method comes in; we want to be able to define a method and accept an arbitrary number of arguments which it can process (please note in most if not all cases the best option for this would be to pass something like a Vector in C++ or an array in PHP, but best practice is not the point of the exercise).

Let’s consider a problem.

We want to have a LineShape function. This function takes a series of Points (a simple class just containing an X and Y coordinate). In a proper system it would then start with the first point and draw a line to each consecutive one but for our example we just want it to print a list of the points it will draw to/from in order.

This could be two points (a single line) or a complex shape of an undetermined total number of points (again note the caveat above that a Vector/List/Array would be the best and safest way to do this in TRW).

So for our implementation we need:

  • A simple Point class
  • A method (LineShape) that takes an arbitrary number of Points and prints out the coordinates
  • Code to create a set of Points and pass them to LineShape

How to do this varies from language to language and, as you might assume, it’s hardest and most dangerous in C++ (because of it’s lack of type safety), slightly easier in Java and PHP (Java because of it’s high type safety and PHP because of it’s lack of any enforced typing).

Variable Length Arguments in C++

To implement in C++ we make use of the va_ functionality provided in stdarg.h. The function is defined as taking the number of parameters passed (int) and then the parameters themselves represented by “…”.

We read the parameter count and then iterate through reading each in turn with va_arg and specifying the type to be used. Note in C++ you must specify the number of parameters being passed when calling the method.

#include <iostream>
#include <stdarg.h>
using namespace std;

// Declare the variable-length argument method
void LineShape(int, ...);

// Our simple Point class
class Point
{
public:
	int x;
	int y;
	Point(int ix, int iy)
	{
		x = ix;
		y = iy;
	}
};

// Definition of LineShape
void LineShape(int n_args, ...)
{
	va_list ap; // arg list
	va_start(ap, n_args); // start on list

	for (int i=1; i<=n_args; i++) // iterate
	{
		// read next argument as Point*
		Point* a = va_arg(ap, Point*);
		cout << a->x << "," << a->y << "\n";
	}
	va_end(ap);
}

int main(int ac, char **av)
{
	Point *a = new Point(10,10);
	Point *b = new Point(15,15);
	Point *c = new Point(10,20);
	LineShape(3, a, b, c);
	return 0;
}

There you have it in C++ (well actually using C libraries); but don’t do it (see above).

Variable Length Arguments in Java

In Java it’s a lot easier as the functionality is built-in to the language. Additionally you don’t need to pass the number of parameters and also the type is determined for the entire set of parameters (in our case Point).

Note that in order for Point to be instantiated as non-static it must be in a seperate file (Point.java).

So our Point class is:

public class Point
{
	public int x;
	public int y;
	Point(int ix, int iy)
	{
		x = ix;
		y = iy;
	}
}

And the main Var.java contains:

public class Var
{
	public static void LineShape(Point... points)
	{
		for (Point p: points)
		{
			System.out.println(p.x + "," + p.y);
		}
	}

	public static void main(String args[])
	{
		Point a = new Point(10,10);
		Point b = new Point(15,15);
		Point c = new Point(10,20);
		LineShape(a,b,c);
	}
}

So in Java we just need to declare a method with Type… name and then iterate through the array in a for loop.

Variable Length Arguments in PHP

PHP isn’t quite as built-in as Java (an actual language construct) but PHP natively provides functions to support variable length parameters to methods such as func_num_args (number of arguments) and func_get_args (arguments as an array).

<?php
class Point
{
	public $x;
	public $y;
	public function Point($ix, $iy)
	{
		$this->x = $ix;
		$this->y = $iy;
	}
}

function LineShape()
{
	$num_args = func_num_args();
	$arg_list = func_get_args();
	for ($i=0; $i < $num_args; $i++)
	{
		$point = $arg_list[$i];
		echo $point->x.",".$point->y."\n";
	}
}

$a = new Point(10,10);
$b = new Point(15,15);
$c = new Point(10,20);

LineShape($a, $b, $c);
?>

 

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.