3

The following code is based on a snippet from here. I want a templated function that accepts a reference to an array of size that is deduced when the function is instantiated:

template<int size>
void myFunction( SomeType(&param)[size] )
{
    //use param and size here
}

//called like this:
SomeType array[SomeConstant];
myFunction( array ); //SomeConstant magically gets into the function as "size"

Now I'm confused with SomeType(&param)[size]. I'd expect the following to work:

template<int size>
void myFunction( (SomeType[size])& param ) {}

but it wouldn't compile.

Why do I need such weird syntax for "reference to array of fixed size"?

20
  • 4
    A better question is, why would you ever used fixed-size arrays? Have programmers really learned nothing from all the buffer-overflow hacks plaguing so much software? I personally blame stupid teachers who teach this stuff in the first place. Commented Jun 23, 2011 at 15:08
  • 3
    Because the C declaration syntax was designed to punish mankind for its sins. Commented Jun 23, 2011 at 15:09
  • 2
    @Blindy: You do notice that the size of the array is known to the function, yes? Commented Jun 23, 2011 at 15:10
  • 2
    @Blindy: The point is that a fixed size array with a known size is precicely as safe as a variable length array with a known size. In fact, in this case it is more safe, because the compiler takes care of the size for you... if the size of the array changes, there is zero risk of myFunction getting called with the wrong size. Commented Jun 23, 2011 at 15:17
  • 1
    For an example of a use of fixed-size arrays that is not dangerous: string literals are fixed-size arrays. std::string foo = "foo"; uses a fixed-size array. It is hardly horrifying. You're wrongly assuming the copying of data willy-nilly into buffers with ad-hoc bounds checking. That is one possible use of fixed-size arrays, and it's inadvisable to do it in a language where you can avoid it since "ad-hoc" checking frequently turns out to be "bug-ridden" checking... Commented Jun 23, 2011 at 15:35

4 Answers 4

4

It's based on the C declaration syntax. Of course, C doesn't have references, but it's meant to mimic the C syntax for pointers. Here's a pointer to an array (in C or C++):

int (*parray)[size];

The idea is that the declaration mimics the usage. It's meant to suggest that later on when you use parray, the expression

(*parray)[0]

(or whatever index) is of type int. Of course, the symmetry breaks down for reference types, since the & is used while declaring them but not referring to them.

Sign up to request clarification or add additional context in comments.

Comments

3

It's for consistency with C array declaration syntax.

With your proposed syntax, you'd also write:

int*[4] x;

instead of

int* x[4];

That's not a bad choice, but it's not what C uses, and C++ tries to be compatible.

Comments

1

The problem with your second declaration becomes what value should be used as the identifier? Should it be param, or should it be SomeType? Because of the parenthesis, the first part of the declaration would be parsed first, but if that's the case, and SomeType was not the identifier, then at what point in the parsing does the identifier get named?

Using the clockwise parsing pattern of C/C++, where the identifier is the the inner-most unknown parsed element (i.e., something that isn't a known token or keyword ... see the link), syntax like

(SomeType[size])& param

would read "SomeType is an array of fixed 'size' that is a reference-type type for some object param" which of course doesn't make any sense since the array has not been declared with the type of object that it is an array of. On the otherhand

SomeType(&param)[size]

using the same parsing rules would read "param is a reference to an array of fixed size that contains objects of type SomeType". The latter is of course the declaration you want, and what makes sense to the C/C++ parser.

Comments

1

When declaring you should follow the rule:

Start form the name, go right when you can, go left when you must.

this rule is completely described in this useful link, and & is handled as *, this is the link:

http://unixwiz.net/techtips/reading-cdecl.html

In you delecration, you put [] before the name of the variable, which is illegal. The rule is that every * and & should come before the name, and every [] and () should come after the name.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.