Adding integers to arrays in C++? - c++

Consider:
int sum(const int numbers[], const int size){
if (size == 0)
return 0;
else
return numbers[0] + sum(numbers+1, size-1);
}
This is a simple recursive function from MIT 6.096 for adding an arbitrary number of integers, and it works.
The thing I cannot understand is in the last line:
How does numbers+1 work, given numbers[] is an int array and you shouldn't be able to add an integer to an int[] constant?

how does "numbers+1" work, given numbers[] is an int array and you shouldn't be able to add an integer to an int[] constant?
There's no int[] constant. numbers is decayed to a pointer and numbers+1 is simple pointer arithmetic applied to the parameter passed to the recursive call.

As a side note to #πάντα ῥεῖ's answer, here are a few clarifications on the terminology:
The following is another way to depict array notation:
The phrase numbers[1] can also be expressed as *(numbers + 1)
Where the * operator is said to dereference the pointer address numbers + 1.
dereference can be thought of in this case as read the value pointed to by.
So, the code in your example is using pointer arithmetic. The phrase numbers + 1 is pointer notation, pointing to the second int location of the pointer numbers. size - 1 is a count of bytes from the memory location starting at numbers to the end of the array.
As to the meaning of decayed:
Generally, within the context of C array arguments, decay conveys the idea that the array argument experiences loss of type and dimension information. Your const int numbers[] is said (arguably) to decay into an int *, therefore no longer able to provide array size information. (Using the sizeof() macro for example does not provide length of array, but size of the pointer.) This also is the reason a second argument is provided, to convey size information.
However, in the context of this question, the meaning of decay is academic, as pointed out by #Ben Voigt: The token sequence const int numbers[], when it appears in a formal parameter list, declares a pointer and not an array. (It never decayed into a pointer because it was a pointer to begin with.)

As πάντα ῥεῖ says int[] decays to int*.
But this sum function is the poor man's solution, you should prefer accumulate:
cout << accumulate(numbers, next(numbers, size), decay_t<decltype(numbers[0])>{});
Live Example
If you have C++17 and a statically allocated array, such as int numbers[size], you can take advantage of cbegin and cend:
cout << accumulate(cbegin(numbers), cend(numbers), decay_t<decltype(numbers[0])>{});
I've attempted to benchmark the recursive sum against accumulate, however sum runs out of stack space before I am able to reach a vector size with a meaningful difference, making accumulate the clear winner.
I associate the type of accumulate's init agument with the type of numbers' elements: decay_t<decltype(numbers[0])>{}. The reason for this is if someone was to come back and change the type of numbers, and not change the type of accumulate's init argument the accumulation would be assigned to the wrong type.
For example if we use the accumulation line: cout << accumulate(cbegin(numbers), cend(numbers), 0), this is fine for int numbers[]. The problem would arise if we switched to define: double numbers[] = {1.3, 2.3, 3.3, 4.3}; but we failed to change the init argument we would sum doubles into an int. This would result in 10 rather than 11.2: http://ideone.com/A12xin

int sum(int *num,int size)
{
int total=0;
/* function to sum integer array */
if (size <= 0) return(ERROR);
while(size--) total+= *num++;
return total;
}
Is faster, more compact, and error tolerant.

numbers is a pointer ; on each iteration the function sum() advances through the array (this is what numbers+1 does), at the same time decreasing size by 1 (--size would work just as well).
When size reaches 0 this is the exit condition, and the recursion ends.

Related

What adding type_t to array means in C++ [duplicate]

Consider:
int sum(const int numbers[], const int size){
if (size == 0)
return 0;
else
return numbers[0] + sum(numbers+1, size-1);
}
This is a simple recursive function from MIT 6.096 for adding an arbitrary number of integers, and it works.
The thing I cannot understand is in the last line:
How does numbers+1 work, given numbers[] is an int array and you shouldn't be able to add an integer to an int[] constant?
how does "numbers+1" work, given numbers[] is an int array and you shouldn't be able to add an integer to an int[] constant?
There's no int[] constant. numbers is decayed to a pointer and numbers+1 is simple pointer arithmetic applied to the parameter passed to the recursive call.
As a side note to #πάντα ῥεῖ's answer, here are a few clarifications on the terminology:
The following is another way to depict array notation:
The phrase numbers[1] can also be expressed as *(numbers + 1)
Where the * operator is said to dereference the pointer address numbers + 1.
dereference can be thought of in this case as read the value pointed to by.
So, the code in your example is using pointer arithmetic. The phrase numbers + 1 is pointer notation, pointing to the second int location of the pointer numbers. size - 1 is a count of bytes from the memory location starting at numbers to the end of the array.
As to the meaning of decayed:
Generally, within the context of C array arguments, decay conveys the idea that the array argument experiences loss of type and dimension information. Your const int numbers[] is said (arguably) to decay into an int *, therefore no longer able to provide array size information. (Using the sizeof() macro for example does not provide length of array, but size of the pointer.) This also is the reason a second argument is provided, to convey size information.
However, in the context of this question, the meaning of decay is academic, as pointed out by #Ben Voigt: The token sequence const int numbers[], when it appears in a formal parameter list, declares a pointer and not an array. (It never decayed into a pointer because it was a pointer to begin with.)
As πάντα ῥεῖ says int[] decays to int*.
But this sum function is the poor man's solution, you should prefer accumulate:
cout << accumulate(numbers, next(numbers, size), decay_t<decltype(numbers[0])>{});
Live Example
If you have C++17 and a statically allocated array, such as int numbers[size], you can take advantage of cbegin and cend:
cout << accumulate(cbegin(numbers), cend(numbers), decay_t<decltype(numbers[0])>{});
I've attempted to benchmark the recursive sum against accumulate, however sum runs out of stack space before I am able to reach a vector size with a meaningful difference, making accumulate the clear winner.
I associate the type of accumulate's init agument with the type of numbers' elements: decay_t<decltype(numbers[0])>{}. The reason for this is if someone was to come back and change the type of numbers, and not change the type of accumulate's init argument the accumulation would be assigned to the wrong type.
For example if we use the accumulation line: cout << accumulate(cbegin(numbers), cend(numbers), 0), this is fine for int numbers[]. The problem would arise if we switched to define: double numbers[] = {1.3, 2.3, 3.3, 4.3}; but we failed to change the init argument we would sum doubles into an int. This would result in 10 rather than 11.2: http://ideone.com/A12xin
int sum(int *num,int size)
{
int total=0;
/* function to sum integer array */
if (size <= 0) return(ERROR);
while(size--) total+= *num++;
return total;
}
Is faster, more compact, and error tolerant.
numbers is a pointer ; on each iteration the function sum() advances through the array (this is what numbers+1 does), at the same time decreasing size by 1 (--size would work just as well).
When size reaches 0 this is the exit condition, and the recursion ends.

typedef of char pointers in c++ [duplicate]

What is the difference between the following declarations:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
What is the general rule for understanding more complex declarations?
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
The third one is same as the first.
The general rule is operator precedence. It can get even much more complex as function pointers come into the picture.
Use the cdecl program, as suggested by K&R.
$ cdecl
Type `help' or `?' for help
cdecl> explain int* arr1[8];
declare arr1 as array 8 of pointer to int
cdecl> explain int (*arr2)[8]
declare arr2 as pointer to array 8 of int
cdecl> explain int *(arr3[8])
declare arr3 as array 8 of pointer to int
cdecl>
It works the other way too.
cdecl> declare x as pointer to function(void) returning pointer to float
float *(*x)(void )
I don't know if it has an official name, but I call it the Right-Left Thingy(TM).
Start at the variable, then go right, and left, and right...and so on.
int* arr1[8];
arr1 is an array of 8 pointers to integers.
int (*arr2)[8];
arr2 is a pointer (the parenthesis block the right-left) to an array of 8 integers.
int *(arr3[8]);
arr3 is an array of 8 pointers to integers.
This should help you out with complex declarations.
int *a[4]; // Array of 4 pointers to int
int (*a)[4]; //a is a pointer to an integer array of size 4
int (*a[8])[5]; //a is an array of pointers to integer array of size 5
The answer for the last two can also be deducted from the golden rule in C:
Declaration follows use.
int (*arr2)[8];
What happens if you dereference arr2? You get an array of 8 integers.
int *(arr3[8]);
What happens if you take an element from arr3? You get a pointer to an integer.
This also helps when dealing with pointers to functions. To take sigjuice's example:
float *(*x)(void )
What happens when you dereference x? You get a function that you can call with no arguments. What happens when you call it? It will return a pointer to a float.
Operator precedence is always tricky, though. However, using parentheses can actually also be confusing because declaration follows use. At least, to me, intuitively arr2 looks like an array of 8 pointers to ints, but it is actually the other way around. Just takes some getting used to. Reason enough to always add a comment to these declarations, if you ask me :)
edit: example
By the way, I just stumbled across the following situation: a function that has a static matrix and that uses pointer arithmetic to see if the row pointer is out of bounds. Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
Output:
0 (0x804a02c): [0, 0]
1 (0x804a034): [0, 0]
2 (0x804a024): [0, 1]
3 (0x804a02c): [1, 2]
4 (0x804a034): [2, 4]
5 (0x804a024): [3, 7]
Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: const int (*border)[3]: that declares border as a pointer to an array of 3 integers that will not change value as long as the variable exists. However, that pointer may be pointed to any other such array at any time. We want that kind of behaviour for the argument, instead (because this function does not change any of those integers). Declaration follows use.
(p.s.: feel free to improve this sample!)
typedef int (*PointerToIntArray)[];
typedef int *ArrayOfIntPointers[];
As a rule of thumb, right unary operators (like [], (), etc) take preference over left ones. So, int *(*ptr)()[]; would be a pointer that points to a function that returns an array of pointers to int (get the right operators as soon as you can as you get out of the parenthesis)
I think we can use the simple rule ..
example int * (*ptr)()[];
start from ptr
" ptr is a pointer to "
go towards right ..its ")" now go left its a "("
come out go right "()" so
" to a function which takes no arguments " go left "and returns a pointer " go right "to
an array" go left " of integers "
Here's an interesting website that explains how to read complex types in C:
http://www.unixwiz.net/techtips/reading-cdecl.html
Here's how I interpret it:
int *something[n];
Note on precedence: array subscript operator ([]) has higher priority than
dereference operator (*).
So, here we will apply the [] before *, making the statement equivalent to:
int *(something[i]);
Note on how a declaration makes sense: int num means num is an int, int *ptr or int (*ptr) means, (value at ptr) is
an int, which makes ptr a pointer to int.
This can be read as, (value of the (value at ith index of the something)) is an integer. So, (value at the ith index of something) is an (integer pointer), which makes the something an array of integer pointers.
In the second one,
int (*something)[n];
To make sense out of this statement, you must be familiar with this fact:
Note on pointer representation of array: somethingElse[i] is equivalent to *(somethingElse + i)
So, replacing somethingElse with (*something), we get *(*something + i), which is an integer as per declaration. So, (*something) given us an array, which makes something equivalent to (pointer to an array).
I guess the second declaration is confusing to many. Here's an easy way to understand it.
Lets have an array of integers, i.e. int B[8].
Let's also have a variable A which points to B. Now, value at A is B, i.e. (*A) == B. Hence A points to an array of integers. In your question, arr is similar to A.
Similarly, in int* (*C) [8], C is a pointer to an array of pointers to integer.
int *arr1[5]
In this declaration, arr1 is an array of 5 pointers to integers.
Reason: Square brackets have higher precedence over * (dereferncing operator).
And in this type, number of rows are fixed (5 here), but number of columns is variable.
int (*arr2)[5]
In this declaration, arr2 is a pointer to an integer array of 5 elements.
Reason: Here, () brackets have higher precedence than [].
And in this type, number of rows is variable, but the number of columns is fixed (5 here).
In pointer to an integer if pointer is incremented then it goes next integer.
in array of pointer if pointer is incremented it jumps to next array

Difference between int* array[] and int (*array)[] [duplicate]

What is the difference between the following declarations:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
What is the general rule for understanding more complex declarations?
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
The third one is same as the first.
The general rule is operator precedence. It can get even much more complex as function pointers come into the picture.
Use the cdecl program, as suggested by K&R.
$ cdecl
Type `help' or `?' for help
cdecl> explain int* arr1[8];
declare arr1 as array 8 of pointer to int
cdecl> explain int (*arr2)[8]
declare arr2 as pointer to array 8 of int
cdecl> explain int *(arr3[8])
declare arr3 as array 8 of pointer to int
cdecl>
It works the other way too.
cdecl> declare x as pointer to function(void) returning pointer to float
float *(*x)(void )
I don't know if it has an official name, but I call it the Right-Left Thingy(TM).
Start at the variable, then go right, and left, and right...and so on.
int* arr1[8];
arr1 is an array of 8 pointers to integers.
int (*arr2)[8];
arr2 is a pointer (the parenthesis block the right-left) to an array of 8 integers.
int *(arr3[8]);
arr3 is an array of 8 pointers to integers.
This should help you out with complex declarations.
int *a[4]; // Array of 4 pointers to int
int (*a)[4]; //a is a pointer to an integer array of size 4
int (*a[8])[5]; //a is an array of pointers to integer array of size 5
The answer for the last two can also be deducted from the golden rule in C:
Declaration follows use.
int (*arr2)[8];
What happens if you dereference arr2? You get an array of 8 integers.
int *(arr3[8]);
What happens if you take an element from arr3? You get a pointer to an integer.
This also helps when dealing with pointers to functions. To take sigjuice's example:
float *(*x)(void )
What happens when you dereference x? You get a function that you can call with no arguments. What happens when you call it? It will return a pointer to a float.
Operator precedence is always tricky, though. However, using parentheses can actually also be confusing because declaration follows use. At least, to me, intuitively arr2 looks like an array of 8 pointers to ints, but it is actually the other way around. Just takes some getting used to. Reason enough to always add a comment to these declarations, if you ask me :)
edit: example
By the way, I just stumbled across the following situation: a function that has a static matrix and that uses pointer arithmetic to see if the row pointer is out of bounds. Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
Output:
0 (0x804a02c): [0, 0]
1 (0x804a034): [0, 0]
2 (0x804a024): [0, 1]
3 (0x804a02c): [1, 2]
4 (0x804a034): [2, 4]
5 (0x804a024): [3, 7]
Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: const int (*border)[3]: that declares border as a pointer to an array of 3 integers that will not change value as long as the variable exists. However, that pointer may be pointed to any other such array at any time. We want that kind of behaviour for the argument, instead (because this function does not change any of those integers). Declaration follows use.
(p.s.: feel free to improve this sample!)
typedef int (*PointerToIntArray)[];
typedef int *ArrayOfIntPointers[];
As a rule of thumb, right unary operators (like [], (), etc) take preference over left ones. So, int *(*ptr)()[]; would be a pointer that points to a function that returns an array of pointers to int (get the right operators as soon as you can as you get out of the parenthesis)
I think we can use the simple rule ..
example int * (*ptr)()[];
start from ptr
" ptr is a pointer to "
go towards right ..its ")" now go left its a "("
come out go right "()" so
" to a function which takes no arguments " go left "and returns a pointer " go right "to
an array" go left " of integers "
Here's an interesting website that explains how to read complex types in C:
http://www.unixwiz.net/techtips/reading-cdecl.html
Here's how I interpret it:
int *something[n];
Note on precedence: array subscript operator ([]) has higher priority than
dereference operator (*).
So, here we will apply the [] before *, making the statement equivalent to:
int *(something[i]);
Note on how a declaration makes sense: int num means num is an int, int *ptr or int (*ptr) means, (value at ptr) is
an int, which makes ptr a pointer to int.
This can be read as, (value of the (value at ith index of the something)) is an integer. So, (value at the ith index of something) is an (integer pointer), which makes the something an array of integer pointers.
In the second one,
int (*something)[n];
To make sense out of this statement, you must be familiar with this fact:
Note on pointer representation of array: somethingElse[i] is equivalent to *(somethingElse + i)
So, replacing somethingElse with (*something), we get *(*something + i), which is an integer as per declaration. So, (*something) given us an array, which makes something equivalent to (pointer to an array).
I guess the second declaration is confusing to many. Here's an easy way to understand it.
Lets have an array of integers, i.e. int B[8].
Let's also have a variable A which points to B. Now, value at A is B, i.e. (*A) == B. Hence A points to an array of integers. In your question, arr is similar to A.
Similarly, in int* (*C) [8], C is a pointer to an array of pointers to integer.
int *arr1[5]
In this declaration, arr1 is an array of 5 pointers to integers.
Reason: Square brackets have higher precedence over * (dereferncing operator).
And in this type, number of rows are fixed (5 here), but number of columns is variable.
int (*arr2)[5]
In this declaration, arr2 is a pointer to an integer array of 5 elements.
Reason: Here, () brackets have higher precedence than [].
And in this type, number of rows is variable, but the number of columns is fixed (5 here).
In pointer to an integer if pointer is incremented then it goes next integer.
in array of pointer if pointer is incremented it jumps to next array

Get the length of an array which contains an element 0 while passing to a function

Is there any way to print length of an array which contains an element 0 and that array has been passed to a function which can have only one argument as the array?
Example:
int arrLen(int arr[])
{
//get size here;
}
int main()
{
int arr[]={0,1,2,3,4,5};
arrLen(arr);
}
There is a limitation in C++ that we can not compare the elements of an array with a NULL if it has a zero, but still asking if there is a way to do that. I can only pass array to function is my limitation.
In your very example, you can use function template to get what you want:
template <size_t N>
int arrLen(int (&arr)[N])
{
return N;
}
The only answer is that you can't get the size of the array once it's been passed as an argument. You have to remember that when passing an array as an argument, it decays to a pointer, and the compiler have no idea of what the pointer actually points to. You should also remember that sizeof is a compile-time operation, the result of a sizeof operation is done by the compiler, and not at runtime.
You either have to put a special end-of-array marker, like strings use the '\0' character to mark the end of a string, at the end of the array (note that this end-of-array marker can be anything that's not supposed to be in the array, be it a zero, -1 or something else). Or you have to pass the length as an argument to the function.
In C when pass an array as an argument to a function, you're passing a pointer to the first element. If you want to pass the size of the array, you should pass it as a separated argument.
You can store the length of the array in the first element of it:
int arr[] = {-1,0,1,2,3,4,5};
arr[0] = sizeof(arr) / sizeof(arr[0]) - 1;
After you do this, you'll get the array's size in arr[0].
There's two ways to achieve what you want:
Know the size of the array - you have to either hard-code it in the function, or pass it as parameter.
Use a sentinel value. When you find the sentinel value, you know you've reached the end of the data. For example, C strings work using \0 as a sentinel.
The latter one seems to be applicable here (e.g. using INT_MIN as sentinel), but unless you have very good reasons, don't do it. Simply pass the length.
Since you control the function that computes the array length, you could decide that a specific int value (or even sequence) such as -1 marks the end of your array. You can then implement your arrLen function like this (with additional improvements for e.g. int overflow):
int arrLen(int arr[])
{
int size = 0;
int* p = arr;
while (*p != -1) {
++size;
++p;
}
return size;
}
then, of course, you need to properly "close" your array on the calling site, or you'll run into trouble:
int arr[]={0,1,2,3,4,5, -1 };
Thanks for the help, but that is my limitation to pass only 1 argument into the function and that can only be an array.
anyways I just wrote that main function to make an understanding, but actually that main function is not available to me. So finally I end up with a function which can get an argument that can be an int array and return the size of array.
I tried with something that to convert my int array into an ascii array of those int values and since a NULL or '\0' can never be equal to a '0', so comparing them with NULL up to the end of an array is possible.
But again I got stuck when I'm going to convert the array, I required the length.

problem with sizeof operator

As i want to find array size dynamically in function, i used sizeof operator. But i got some unexpected result.
here is one demo program to show you, what i want to do.
//------------------------------------------------------------------------------------------
#include <iostream>
void getSize(int *S1){
int S_size = sizeof S1/sizeof(int);
std::cout<<"array size(in function):"<<S_size<<std::endl;
}
int main(){
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S);
std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
return 0;
}
//------------------------------------------------------------------------------------------
compilation command : g++ demo1.cc -o demo1 {fedora 12}
output:
array size(in function):2
array size:19
please explain ,why this is happening.
what can be done to solve this problem.
void getSize(int *S1)
When you pass an array to this function, it decays to pointer type, so sizeof operator will return the size of pointer.
However, you define your function as,
template<int N>
void getSize(int (&S1)[N])
{
//N is the size of array
int S_size1 = N;
int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
std::cout<<"array size(in function):"<<S_size1<<std::endl;
std::cout<<"array size(in function):"<<S_size2<<std::endl;
}
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before
then you can have the size of array, in the function!
See the demonstration yourself here : http://www.ideone.com/iGXNU
Inside getSize(), you're getting size of pointer, which is 8 bytes (since you're probably running 64-bit OS). In main(), you're getting size of array.
If you want to know array size, pass result of sizeof(S) as additional argument to getSize().
More alternatives would be using some container (like std::vector) or turning function into template function, as Nawaz proposed.
S is an int *, a pointer to an integer, which is a memory address, which is on your machine twice the size of an integer.
If you want the size of the array (I.e., the number of elements), you can't get that directly in pure C. But since this is a c++ question, there is a way: use a vector, which has a size() method.
Actually, this isn't quite true: within the function that you declare S (and only if it's explicitly initialized at compile time as you do in your example -- even new int[19] doesn't work), the sizeof operator actually does get the correct answer, which is why c++ allows you to do this:
int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );
and then you can use v.size() (see these docs).
The template version by Nawaz elsewhere is another excellent suggestion which forces the compiler into carrying the full information about the construction of the c++ array around (again, note that this is all known at compile time, which is why you can be explicit about the size in the argument).
you are getting the size of the pointer to the array. If you want the size of the array you have to multiply the number of elements by the size of each element.
You will have to pass the size of the array to the function.
Since you are only passing a pointer to the first element in the array, your function has no information on its actual size.
void getSize(int *S1, size_t size)
{
int S_Size = sizeof(*S1) * size;
}
This is redundant though, if you think about it :D
To prevent this type of accidental misuse of sizeof, you can define a function which only works on arrays:
template<class T, int N>
int array_size(T (&)[N]) {
return N;
}
If you use this in your code, you'll see a compiler error when applied to S1, as it is not an array. Plus, it's shorter and a bit more explicit than sizeof array / sizeof array[0] (using the size of the first item means you don't have to repeat the array type).
This also already exists in Boost in a more general form (accepting anything with a size method, such as std::vector).