Passing an array of 'typedef struct' to a function

I have the following situation:

Ac file:

typedef struct element
{
    uint16_t value_raw;
    float value_scaled;
    char *desc;
} element;

element sv[REG_READ_COUNT];

Ah file:

typedef struct element element;

Bc file:

#include "A.h"
void dostuff (element sv[]) { } 

at compile time, I get "error: array type has an incomplete element type" to determine function argument in Bc

What is the right way to do this? How to pass an array of type 'element' to a function?

+4
source share
5 answers

B B.c, elementis an incomplete type (it is not defined in A.h, only in A.c). C forbids array declarators with incomplete element types (as you discovered). Here is the relevant text from project C99:

6.7.5.2 Manifest declaration

Limitations

  • static, [ ] *. ( ), . , . . static , .

. , , : , typedefs, ..

, A.h. , dostuff (, "" - ), void dostuff(element *sv).

+6

.

struct element;
void dostuff (struct element sv[]) { } 

clang gcc coliru: http://coliru.stacked-crooked.com/a/e5e314deef461290
: GCC clang .

:

6.7.6.3 ( )

[...]
4 , .
[...]
7 '' '' , ( ) - , [ ] . static [ ] , , , , .

, , , , .

6.2.5

[...]
20 , :

  • -, . . . , T, '' . '' .

.

: , .


forward , , .

.

+2

Deduplicator.

, element *sv. B.c typedef struct element element;. , element.

"" dostuff - sv, , , struct element A.c A.h.

0

, , OP, , , , C . , , , , element *, ELEM_HANDLE, . ELEM_HANDLE , . , , ( element.h) .

element.h:

#include <stdint.h>

typedef struct element element;
typedef element *ELEM_HANDLE;

extern element *element_new();
extern void element_delete(element *elem);
extern void element_set_value_raw(element *elem, uint16_t value_raw);
extern uint16_t element_get_value_raw(element *elem);
extern void element_set_value_scaled(element *elem, float value_scaled);
extern float element_get_value_scaled(element *elem);
extern void element_set_desc(element *elem, char *desc);
extern char *element_get_desc(element *elem);

element.c:

#include <stdint.h>
#include <stdlib.h>

typedef struct element
{
        uint16_t value_raw;
        float value_scaled;
        char *desc;
} element;

element *element_new()
{
        return calloc(1, sizeof(element));
}

void element_delete(element *elem)
{
        free(elem);
}

void element_set_value_raw(element *elem, uint16_t value_raw)
{
        elem->value_raw = value_raw;
}
uint16_t element_get_value_raw(element *elem)
{
        return elem->value_raw;
}

void element_set_value_scaled(element *elem, float value_scaled)
{
        elem->value_scaled = value_scaled;
}

float element_get_value_scaled(element *elem)
{
        return elem->value_scaled;
}

void element_set_desc(element *elem, char *desc)
{
        elem->desc = desc;
}

char *element_get_desc(element *elem)
{
        return elem->desc;
}

testelem.c:

#include <stdio.h>
#include "element.h"

#define REG_READ_COUNT 2

void dostuff(element *sv[], int arrLen)
{
        int index;
        element *curelem;
        uint16_t raw;
        float scaled;
        char *desc;

        for (index = 0; index < arrLen ; index++){
                curelem = sv[index];
                raw = element_get_value_raw(curelem);
                scaled = element_get_value_scaled(curelem);
                desc = element_get_desc(curelem);
                /* Do more interesting stuff here */
                printf("%s, %d, %.4f\n", desc, raw, scaled);
        }
}

int main()
{
        unsigned int index;
        element *sv[REG_READ_COUNT]; /* array of element pointers*/
        char desc1[] = "The answer to everything";
        char desc2[] = "OtherStuff";

        /* Initialize an array of pointers to element items */
        for (index = 0; index < sizeof(sv) / sizeof(element *); index++)
                sv[index] = element_new();

        element_set_value_raw(sv[0], 42);
        element_set_value_scaled(sv[0], 6.66f);
        element_set_desc(sv[0], desc1);
        element_set_value_raw(sv[1], 123);
        element_set_value_scaled(sv[1], 456.7f);
        element_set_desc(sv[1], desc2);

        dostuff(sv, REG_READ_COUNT);

        /* free the array of pointers to element items*/
        for (index = 0; index < sizeof(sv) / sizeof(element *); index++)
                element_delete(sv[index]);

        return 0;
}

, , dostuff . . ( ) C89 ++ ( , .c .cpp).

, - , C. , , element. , , . element.cpp, , , ( ). , , , ().

, ( ) C . (.so files) , C.

0

A.h typedef struct element element B.c, , , . . , , typedef A.c A.h. , , .

, ( ) , - .

:

typedef struct element element;
#define REG_READ_COUNT 100

void dostuff (element *sv[])
{
    sv++; /* get next pointer to element */
};

int main()
{
    element *sv[REG_READ_COUNT]; /* array of pointers to element */
    dostuff(sv);
}

, -, . - ( ), .

, ( ), , C. , . , .

6.7.5.2

static, [] *. ( ), . , . . static , .

, , . - . - . , .

, . , ( ), :

typedef struct element element;
#define REG_READ_COUNT 100

void dostuff (element *sv) /* Completely legal but useless if you intend to use it as an array */
{
    sv++; /* This should fail - as we are doing array arithmetic on
           * an incomplete type. Can't find the starting point of the next
           * array element without knowing the size of the object */
};

int main()
{
    element sv[REG_READ_COUNT]; /* array of elements will also fail - size of object unknown */
    dostuff(sv);
}

. sv ( nneonneo ). , . ( ++ ) , . ++ - - undefined ( , , ). ISO/IEC 9899: TC2 :

6.3.2

6.3.2.1 Lvalues,

     
  

...

         

2 , sizeof, , ++     , - . ,      l, , ,      ( lvalue). lvalue ,      lvalue;     . lvalue ,     undefined

  

-1

All Articles