0

stuck, please help. I followed this but cannot fix it !! argh ! Why does a 1B (uint8_t) work, but the 4B int or uin16_t fail ?

error: invalid type argument of unary '*' (have 'int')

uint16_t current_frameLength =0;
uint16_t plc_tx_count = 0;

typedef struct
{
    uint8_t     Nsdu[R_DEMO_APP_NSDU_BUFFER_SIZE];
    uint16_t    position;
    uint16_t    frameLength;
} ota_buff_t;

typedef struct
{
    //ota_buff_t    (*buf_ptr)[]; //pointer to array of buf_ptr
    ota_buff_t  *buf_ptr; //pointer to array of buf_ptr
    uint8_t     buf_entry;
} ota_list_t;

    ota_list_t  ota_list;
    
    ota_buff_t *rob_buf = malloc(sizeof(ota_buff_t)*5);
    ota_list.buf_ptr = rob_buf; //enter the address of the buffer to the pointer

    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu ) = 0xD0;
    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu +1) = 0xD0;
    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu +2) = plc_tx_count & 0x00FF;
    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu +3) = plc_tx_count >>8; //POST auto-increment
    *(ota_list.buf_ptr[ota_list.buf_entry].frameLength) = current_frameLength;

the only line that has a compile issue is the last, with assigning the contents of variable 'current_frameLength' to a defined uin16_t variable !!!

error: invalid type argument of unary '*' (have 'int')

5
  • First of all, please copy-paste the full and complete build-log into your question. Secondly, add a comment on the line in the shown code where you get the error. Thirdly, what is the type of the frameLength member? Is it a pointer you can dereference? Is the problem because you copy-pasted a little too much? Commented Jan 13, 2024 at 21:56
  • On a different note, for any pointer or array p and index i, the expression *(p + i) is exactly equal to p[i]. Please settle on using only one of those ways to get an element from an array. I suggest the array-index syntax. Inconsistent use of operators makes the code harder to read and understand. And using array-index syntax would also have helped you discover the copy-paste mistake you made much easier. Commented Jan 13, 2024 at 21:57
  • note, that this works: ota_list.buf_ptr[ota_list.buf_entry].frameLength = current_frameLength; but isn't this copying the address of the variable not the value in it? i.e i need the contents of the variable 'current_frameLength', that's why i was using the unary character * since its a pointer we are assigning the value to Commented Jan 13, 2024 at 22:08
  • You dereference a pointer, to get the value that the pointer is actually pointing to. You can't dereference something which isn't a pointer. And neither frameLength nor current_frameLength are pointers. They are actual values. You don't copy addresses or locations, you copy values. Commented Jan 13, 2024 at 22:13
  • 2
    for later, ota_list.buf_entry is uninitialized so ota_list.buf_ptr[ota_list.buf_entry] invokes undefined behavior Commented Jan 13, 2024 at 22:15

1 Answer 1

1

Why does a 1B (uint8_t) work, but the 4B int or uin16_t fail ?

First of all it has nothing to do with size of type.

This works :

    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu ) = 0xD0;
    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu +1) = 0xD0;
    ...........
    ...........

because Nsdu is an array and these statements are assigning a value a member or array Nsdu.

From C17 Standard [6.5.2.1 Array subscripting]:

[emphasis added]

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary+ operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2 -th element of E1 (counting from zero).

Based on the reference, this

    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu ) = 0xD0;

is equivalent to

    ota_list.buf_ptr[ota_list.buf_entry].Nsdu[0] = 0xD0;

and this

    *(ota_list.buf_ptr[ota_list.buf_entry].Nsdu +1) = 0xD0;

is equivalent to

    ota_list.buf_ptr[ota_list.buf_entry].Nsdu[1] = 0xD0;

and so on..

Hence, those statements are simply assigning a value to the members of Nsdu array.

Now coming to the error that you are getting on the statement:

    *(ota_list.buf_ptr[ota_list.buf_entry].frameLength) = current_frameLength;

error:

error: invalid type argument of unary '' (have 'int')*

This error indicates that you are trying to dereference an int type.

This is an integer:

ota_list.buf_ptr[ota_list.buf_entry].frameLength

You can dereference a pointer, but you cannot dereference an integer.

Seems like, you are confused with buf_ptr which is a pointer pointing to rob_buf which is a dynamically allocated memory and, that's why, you are trying to dereferencing it. But you don't need to dereferencing it because you already accessing the memory using the [] operator.

The precedence of . (member access) and [] (array subscripting) operator is same, so the statement will be processed as

(ota_list.buf_ptr)[ota_list.buf_entry].frameLength

Based on C17#6.5.2.1[Array subscripting]$2, it is equivalent to

(*((ota_list.buf_ptr) + (ota_list.buf_entry))).frameLength = current_frameLength;

which is equivalent to

((ota_list.buf_ptr) + (ota_list.buf_entry))->frameLength = current_frameLength;

Hope this helps. Let me know, if you have any further questions.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much for taking the time with such a thorough answer. much appreciated.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.