1

For some context, I am familiar with C programming (not an expert but a daily user) and also MATLAB. I have used C++ minimally and not recently.

I had recently started looking into the MEX functionality of MATLAB as I hadn't ever looked at it before. While I was working through a basic example I noticed something I had not seen before in the entry point function mexFunction, copy/pasted from the docs below.

The output and input arguments are returned as pointers of type mxArray but with an empty bracket (e.g., mxArray *plhs[]). Coming from C I would have just expected mxArray *plhs. I can also understand you might want to return multiple types like scalars, matrices, etc. so maybe you want a pointer to pointers so wouldn't you do mxArray **plhs?

From this post here I understand the syntax mxArray *plhs[] means an array of pointers. Is that different than doing mxArray **plhs?

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
/* variable declarations here */

/* code here */
}
Nukesub
  • 191
  • 5
  • Closely related: https://stackoverflow.com/questions/33746434/double-pointer-vs-array-of-pointersarray-vs-array – Déjà vu Mar 18 '23 at 18:31
  • 4
    `mxArray *plhs[]` declares `plhs` to be an array of `mxArray*` pointers. `mxArray *plhs` would be an array of `mxArray` objects, a different thing entirely. `mxArray *plhs[]` is indeed equivalent, in the function parameter list, to `mxArray **plhs` – Igor Tandetnik Mar 18 '23 at 18:47

1 Answers1

2

In int arr[...] arr is (represents) the address of the 1st element of arr.

In int *p p contains an address to an int (actually, similarly to arr, p is (represents) the address where an address to an int is, but that's maybe confusing).

When indexing arr, arr[i] and p[i], the compiler performs a similar calculation

  • arr[i] => *(arr + i*sizeof(int))
  • p[i] => *((p) + i*sizeof(int))

if there is a slight difference here, is that the compiler uses directly the address of arr, while it takes the value of p (there is an indirection). If p = arr

arr -> int0 int1 int2 ...
p -> (address of arr) -> int0 int1 int2

but practically that indirection does not affect how the code is written.

Answering @CrisLuengo:

if there is a slight difference here, is that the compiler uses directly the address of arr, while it takes the value of p (there is an indirection).” I don’t understand what you are saying here. The two are identical and produce identical code.

Actually no ; these pieces of code

int arr[5];                      int *p;
int x = arr[1];                  int x = p[1];

the int x = ... produces the following assembly

# arr.c:6: int x = arr[1];            # p.c:6: int x = p[1];
movl -28(%rbp), %eax # arr[1], tmp84  movq -8(%rbp), %rax # p, tmp84
movl %eax, -36(%rbp) # tmp84, x       movl 4(%rax), %eax  # MEM[(int *)p_2(D) + 4B], tmp85
                                      movl %eax, -12(%rbp) # tmp85, x

Please note that in this particular example, if the code is compiled with optimizations, the compiler may be able to skip the step of reading the value of p and directly use the address of arr, resulting in similar assembly code for accessing arr[1] and p[1]. However, in general, accessing an array element is typically faster than accessing an element through a pointer due to the additional step of retrieving the pointer's value.


A difference, is that arr being an address, is fixed (arr++ and arr = arr2 are illegal). But p contains a value (an address) that can be changed, incremented etc.

And interesting aspect of the similarity is when passing arr to a function

void f(int a[]) { ... }
f(arr);

The function f takes a parameter which is variable. f can take arr, arr2, ... Thus a in f is treated like a pointer to an int

void f(int a[]) { int y = *a++ ; int x ; a = &x; ... }

Int your case of mxArray *plhs[] and mxArray **plhs this is the same logic. But, instead of int

  • mxArray *plhs[] is an array of pointers to mxArray
  • mxArray **plhs is a pointer to a pointer to a mxArray
Déjà vu
  • 28,223
  • 6
  • 72
  • 100
  • “*if there is a slight difference here, is that the compiler uses directly the address of arr, while it takes the value of p (there is an indirection).*” I don’t understand what you are saying here. The two are identical and produce identical code. It’s just different syntax for the same thing. – Cris Luengo Mar 18 '23 at 19:43
  • @CrisLuengo Hi Cris. I tried to explain the sentence in the answer, please give it a look. – Déjà vu Mar 19 '23 at 07:20
  • 2
    Yes, `Int arr[5]` is a static array, the compiler knows the location of each element, the pointer `arr` is never actually stored. But that doesn’t apply to OP’s case. I think that is why I was confused by the explanation. Thanks for clarifying! – Cris Luengo Mar 19 '23 at 13:56