0

In our legacy C/C++ code I encounter two versions of signatures

void foo1(double *vec, int n)

and

void foo2(double vec[], int n)

But there is no difference in the handling of the parameter vec inside of the methods e.g.:

void foo2(double vec[], int n){
    for(int i=0;i<n;i++)
      do_something(vec[i]);
}

Is there any difference between the first version (double *) and the second (double ..[])? In which situations should a version be preferred over the other?

Edit: After the hint of @Khaled.K I tried to compile:

void foo(double *d, int n){}
void foo(double d[], int n){}

and got a compile error due to redefinition of void foo(double *d, int n). So double *vec and double vec[] mean the same.

The still open question is which version should be used when.

ead
  • 32,758
  • 6
  • 90
  • 153

5 Answers5

5

It's the same. From the standard:

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

So there is no difference. I would use * instead of [] to avoid confusion, unless it's something like char* argv[], then it might be passable.

user6412786
  • 208
  • 1
  • 6
  • 1
    I would say use both to document intent of the parameter better: `*` when function expects parameter to be single item, and `[]` when it expects it to be multiple items. – user694733 Jun 02 '16 at 06:25
  • I don't understand what do you mean by the last sentence. Can you elaborate? – 2501 Jun 02 '16 at 07:02
  • @user694733 want to say that `void foo2(double *)` "**might help**" in deciphering that a double variable is passed, since plain meaning of `double *` is simply a pointer to double or address at which a double is stored. `void foo2(double [])` might help in deciphering inside `foo2` that an array of double is passed. – sameerkn Jun 02 '16 at 07:17
1

Here is the relevant quote from K&R 2nd (*), starting at the bottom of page 99:

As formal parameters in a function definition,

char s[];

and

char *s;

are equivalent; we prefer the latter because it says more explicity that the parameter is a pointer. When an array name is passed to a function, the function can at its convenience believe that it has been haded either an array or a pointer, and manipulate it accordingly. It can even use both notations if it seems appropriate and clear.

(*) Kernighan & Ritchie: "The C Programming Language" (second edition)

Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
1

There is no bound check in c. As you know that the array name itself act as a pointer(with special properties). Whenever you pass an array as an argument to a function, it will internally passed as a pointer of the corresponding type. That is why you need to pass the length of the array as well if you want to do some operation on bound check. Compiler generates the same signature(object code) for both pointer and array as a formal argument. You can use both invariable as per your choice. Below is a simple example:

#include <iostream>
void arrayParamTest(int arr[])
{
}
int main()
{
    int arr[] = {10, 20};
    arrayParamTest(arr);
}

Now compile this and lets see the symbols:

techie@gateway2:myExperiments$ nm a.out | grep "arrayParamTest"
00000000004006e7 t _GLOBAL__I__Z14arrayParamTestPi
0000000000400674 T _Z14arrayParamTestPi 

See compiler generates symbol with "Pi" as argument. Pi means pointer of type int. Hope this will help. :-)

sagar
  • 367
  • 2
  • 12
1

Array and pointers are different but some properties of array and pointers are look similar.

In this case there is no difference between double *vec and double vec[].

But whenever you taken array and initialized with some values and then you passed that array as function argument.

In function signature if you use double *vec then unexpectedly u would try to free that memory dynamically in function definition then it will throw an exception at runtime i.e this may due to a corruption of the heap.

example:

#include<stdio.h>
#include<stdlib.h>
void foo1(int *arr);
int main()
{
    int arr[] = {10, 20};
    foo1(arr);

    return 0;
}
void foo1(int *arr)
{
    printf("in array\n");
    free(arr);
}

Why means

--> Arrays are static in nature once you allocated memory you cannot free and resize dynamically.

--> This is the one case which confuses using double *vec.

--> Except like this situations both signatures are similar.

Prakash
  • 100
  • 1
  • 1
  • 8
-2

double *vec implies that there is only one double value that is pointed to by vec. And double []vec implies that there is an array of doubles. From the code you show it appears that the array of doubles is what you want. Using double *vec for array operations is bound to lead to trouble.

Marichyasana
  • 2,966
  • 1
  • 19
  • 20