0

what is this syntax for double x[]?

Is it a C way to declare an array?

If I have a function like

void evaluate(double x[], double *f)
{
   // evaluate
}

Can I pass a parameter x with any length?

Curious
  • 2,783
  • 3
  • 29
  • 45
kiriloff
  • 25,609
  • 37
  • 148
  • 229
  • 7
    @Borgleader C and C++ are bad languages for "try and see". – Seth Carnegie Sep 27 '12 at 16:13
  • 5
    The syntax `double x[]` when used in a function argument list is _exactly the same_ as `double* x`. – Seth Carnegie Sep 27 '12 at 16:13
  • If you try it you will see that you can. – Rontogiannis Aristofanis Sep 27 '12 at 16:15
  • Spend a minute and try it out, to see that yes you can... – Curious Sep 27 '12 at 16:18
  • 1
    You'll "see that you can", but not whether you *may*. You'll see that your implementation allowed it, and that it appeared to work. By the same metric it is possible to "see that you can" store values off the ends of arrays, violate strict aliasing, and all kinds stuff that the silly old standard thinks aren't allowed. At best, if you have an option like `-pedantic-errors` on, then testing it shows that it's legal syntax. To learn what values are OK (in this case how long the array can be), you need to actually learn the language rather than mashing at the keyboard and seeing what "works" ;-) – Steve Jessop Sep 27 '12 at 17:32

7 Answers7

5

A parameter of array type behaves exactly like it is a pointer. You can not truly pass an array as a function argument. However, this syntax gives the illusion that you can for the sake of readability. So your function is equivalent to:

void evaluate(double *x, double *f)
{
  // evaluate
}

From §8.3.5/5 of ISO/IEC 14882:2011:

After determining the type of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively.

An expression that denotes an array will decay to a pointer to its first element, so you can still do this:

void evaluate(double x[]);
int array[] = {1, 2, 3, 4, 5};
evaluate(array); // The array decays to a pointer to its first element

From §4.2:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

So yes, you can indeed pass an array of any length. In reality, you are just passing a pointer to the first element. You will, however, need to pass the length of the array as well, if you need it.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
4

Arrays can be confusing, because in most contexts the name of an array decays into a pointer to its first element. So:

double x[3];          // x is an array of 3 doubles
void f(double x[3]);  // f takes a pointer to double
f(x);                 // calls f with the address of x[0]

The reason for having the array type decay into a pointer for f is so that you don't have to have a separate function for every array size:

double x[3];
double y[4];
void f(double x[3], int size) {
    for (int i = 0; i < size; ++i)
        std::cout << x[i] << ' ';
    std::cout << '\n';
}
f(x, 3);
f(y, 4);

It works the same way if the argument is double*x, double x[], double x[3], double x[17], double x[]; in all of these cases, x is treated as double*.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
3

Inside the parameter list of a function, double x[] is same as double *x.

can I pass a parameter x with any length?

Yes, you can pass. But there's no way to know the length of the array x in the function evaluate. So you probably want to pass the length as well.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
P.P
  • 117,907
  • 20
  • 175
  • 238
  • 1
    Just a caution: there are cases where `double x[]` is not the same as `double*x`. For example, `double x[] = { 1.1, 2.3, 3.3 };`. This defines `x` as an array of 3 doubles, with the values from the initializer. In the function call, though, as you say, it's equivalent to `double*x`. – Pete Becker Sep 27 '12 at 16:22
  • @PeteBecker Agreed, I took the liberty of clarifying the answer. – fredoverflow Sep 27 '12 at 17:33
2

C FAQ, Section 6.4

Since arrays decay immediately into pointers, an array is never actually passed to a function. You can pretend that a function receives an array as a parameter, and illustrate it by declaring the corresponding parameter as an array:

  void f(char a[])
    { ... }

Interpreted literally, this declaration would have no use, so the compiler turns around and pretends that you'd written a pointer declaration, since that's what the function will in fact receive:

  void f(char *a)
    { ... }

There's nothing particularly wrong with talking about a function as if it ``receives'' an array, if the function is traditionally used to operate on arrays, or if the parameter is naturally treated within the function as an array.

This conversion of array-like declarators into pointers holds only within function formal parameter declarations, nowhere else. If the conversion bothers you, you're under no compulsion to make use of it; many programmers have concluded that the confusion it causes outweighs the small advantage of having the declaration ``look like'' the call or the uses within the function. (Note that the conversion happens only once; something like char a2[][] won't work. See questions 6.18 and 6.19.)

In other words, in a function parameter declaration, an array with unspecified length is the same as a pointer.

Thom Smith
  • 13,916
  • 6
  • 45
  • 91
1
void evaluate(double x[], double *f)
{
   // evaluate
}

is actually equivalent to:

void evaluate(double *x, double *f)
{
   // evaluate
}

in C and C++.

It means the type of the x parameter is double * in both cases.

ouah
  • 142,963
  • 15
  • 272
  • 331
0

yes in c the array is declared like that

good read

  1. Char array declaration and initialization in C
  2. Simple C array declaration / assignment question
Community
  • 1
  • 1
NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
  • It is true, however when declared as formal parameters, arrays are equivalent to pointers. They are treated the same in memory (the compiler passes just the address) and have the same semantics. – imreal Oct 05 '12 at 20:10
0

The argument x to your function is an array of unspecified length. That means that you can pass any array of type double to it, no matter the size. You can also pass a pointer to a double as argument.

There is one caveats though: You can't use the sizeof operator on the array x, as it doesn't have a size.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621