# Tags and VarArgs

Although Portfolio TagArg calls traditionally use static arrays of TagArg structures to define their parameters, a much superior approach is possible by using the C VarArgs capability.

VarArgs lets C routines like `printf()` accept a variable number of parameters. You can use VarArgs to construct arrays of TagArg structures on the fly within a function call you are making. This is generally easier to write, understand, and maintain than static arrays.

Most Portfolio functions that accept TagArg arrays as parameters also have VarArgs counterparts. These counterparts have the same names as the regular functions, with the addition of a VA suffix to identify them as VarArgs.

For example, the `CreateItem()` kernel function accepts an array of TagArg structures as a parameter. The `CreateItemVA()` function is identical in purpose and function, except that it uses a VarArgs list of tags instead of a pointer to an array.

To build up a tag list on the stack, you enumerate all commands and their arguments in sequence, separated by commas, and terminate them with a `TAG_END` tag command. Here are examples of using `CreateItem()` and `CreateItemVA()` to create a message port.

Example 1: Creating a message port

``

    static TagArgs tags[] =
    {
        {CREATEPORT_TAG_SIGNAL,   0},
        {CREATEPORT_TAG_USERDATA, 0},
        {TAG_END,              0}
    };

    {
    Item mp;

        tags[0].ta_Arg = (void *)sigMask;
        tags[1].ta_Arg = (void *)userData;
        mp = CreateItem(MKNODEID(KERNELNODE,MSGPORTNODE),tags);
    }

    {
    Item mp;

        mp = CreateItemVA(MKNODEID(KERNELNODE,MSGPORTNODE),
                          CREATEPORT_TAG_SIGNAL,   sigMask,
                          CREATEPORT_TAG_USERDATA, userData,
                          TAG_END);
    }

As you can see, the version using `CreateItemVA()` is easier to understand. All the definitions pertaining to the tags can be kept within the function call itself, instead of requiring a separate array.