...
Some template metaprogramming techniques that employ "substitution failure is not an error" (SFINAE) use variadic functions to implement compile-time type queries, as in:
| Code Block |
|---|
typedef char True;
typedef struct { char a[2]; } False;
template <typename T>
True isPtr(T *);
False isPtr(...);
#define is_ptr(e) (sizeof(isPtr(e)) == sizeof(True))
|
...
This example uses a variadic function to concatenate an arbitrary number of null-terminated character sequences (NTCS) in a single NTCS. Each call to the function must use a null pointer value to mark the end of the argument list.
| Code Block | ||
|---|---|---|
| ||
#include <cstdarg>
char *concatenate(char const *s, ...)
{
// code to actually concatenate the strings
}
char *separator = /* some reasonable value */;
char *t = concatenate("hello", separator, "world", NULL);
|
Calling this function without the trailing null pointer, or with an argument of any type other than "pointer to possibly-CV-qualified char" yields undefined behavior:
| Code Block | ||
|---|---|---|
| ||
char *u = concatenate("hello", separator, "world"); // undefined behavior
char *v = concatenate("hello", ' ', "world", NULL); // undefined behavior
|
...
Rather than use a variadic function, you can use a chain of binary operations:
| Code Block | ||
|---|---|---|
| ||
#include <string>
string separator = /* some reasonable value */;
string s = "hello" + separator + "world";
|
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
DCL38 DCL31-CPP | 3 (high) | 2 (probable) | 3 (low) | P18 | L1 |
...