0

I have a union declared like:

typedef union {
    mpls_vpls_t Vpls_dat; //typedef struct
    mpls_vpws_t Vpws_dat; //typedef struct
}ser_cache_t;

and I allocate memory for it:

ser_dat_ch = calloc(LABEL_T_CNT,sizeof(ser_cache_t));
if (ser_dat_ch == NULL)
    return ERROR;

while static ser_cache_t *ser_dat_ch = NULL; is global.

Now I want to populate my union with data and hence I wantto pass a pointer to it to a function like:
rv = switch_mpls_vpws_data_get(lab, &ser_dat_ch->Vpws_dat[lab]);
But here the compiler screams: expression must have pointer-to-object type why so, won't &ser_dat_ch->Vpws_dat[lab] resolve to the address I'm looking for?

stdcerr
  • 13,725
  • 25
  • 71
  • 128
  • 3
    what is `mpls_vpws_t`? If that's not an array typedef, you obviously can't use `Vpws_dat[lab]`. Maybe you meant `&ser_dat_ch[lab].Vpws_dat` – M.M Sep 28 '16 at 19:37
  • @M.M Both structures are `typedef struct` – stdcerr Sep 28 '16 at 19:39
  • You can't. C does not support pass by reference. But you can pass a pointer to the union (aka its address). See [ask], provide a [mcve]. You also want to read about operator preceedence. – too honest for this site Sep 28 '16 at 19:46
  • 1
    saying "C does not support pass by reference" is like saying "C does not support linked lists" – M.M Sep 28 '16 at 19:59
  • 1
    @M.M Olaf is actually right - You may say, C *simulates* PBR by passing around pointers. Effectively, it's the same thing, except when it isn't (you can't pass an **array** by reference, because it loses its array traits) – tofro Sep 28 '16 at 20:02
  • @tofro You can pass a pointer to an array, just the same as a pointer to any other type. The array doesn't lose its array traits. You don't see it very often because passing a pointer to the array's first element suffices for most purposes and has simpler syntax – M.M Sep 28 '16 at 20:03
  • @M.M If it were a *true reference*, you could treat it with `sizeof` and you'd get the size of the array. But you cannot. And exactly that array trait is lost. I hope you don't mix up C and C++ here. We're talking C – tofro Sep 28 '16 at 20:08
  • @tofro yes, you can use `sizeof` and get the size of the array. Yes this is a C question. – M.M Sep 28 '16 at 20:17
  • @M.M Now you've made me interested. Can you give an example? My compilers can't do that. – tofro Sep 28 '16 at 20:18
  • @tofro [see here](http://stackoverflow.com/questions/1810083/). I suspect you are mixing up "pointer to array" with "pointer to first element of array". The latter loses type information (i.e. length) about the array but the former doesn't – M.M Sep 28 '16 at 20:23
  • 1
    Nice, thanks. I even used to know that long ago but apparently decided to forget because you don't use it much, normally. – tofro Sep 28 '16 at 20:27

2 Answers2

2

I assume you have an array of such unions and one pointer to the start of that memory. Then, accessing one of the ith element's structure member would look like

ser_dat_ch[i].Vpws_dat

and a pointer to that union is

&(ser_dat_ch[i])

and a pointer to one of the structs in the union (that is apparently what you're looking for) is

&(ser_dat_ch[i].Vpws_dat)
tofro
  • 5,640
  • 14
  • 31
0

I can't comment to your post (not enough reputation). The error you're getting usually hints that the function parameter is not the correct type for the pointer. I.e. passing a single dimension pointer to a multi dimension pointer.

Additionally, your syntax is problematic:

rv = switch_mpls_vpws_data_get(lab, &ser_dat_ch->Vpws_dat[lab]);

&set_dat_ch->Vpws_dat[lab] is messy syntax. To be honest, I'm not even sure what would evaluate first Vpws_dat[lab] then ser_dat_ch-> then finally &. You should just simplify this (although through parenthesis you could get the desired effect). Either pass the internal struct ser_dat_ch->Vpws_dat and retrieve the variable inside the function, or prior to the function do something like:

int *var = ser_dat_ch->Vpws_dat

And then just pass var to the function. Note: I just used an int* because I'm unsure what the internal implementation is.

nullverb
  • 82
  • 4