-2

I have an array of zero cell and i want to dispay his size. my code is:

#include <stdio.h>
#include <string.h>
#include <stdint.h>

typedef struct ts_ff {

    uint8_t reserved[0];
} TS_fact;

int main(void) {
    TS_fact ts_factory;
    printf("size of reserved is %zu Bytes\n",sizeof(ts_factory));

   return 0;
}

But the return of this code return 0 Bytes not 1 Byte for this array cell.

size of reserved is 0 Bytes

Why the compiler do this ?

craken
  • 1,411
  • 11
  • 16
  • One cell? I see zero cells. – gnasher729 Mar 16 '16 at 13:14
  • 2
    *array of one cell* => Where? – Thomas Ayoub Mar 16 '16 at 13:14
  • ok. SO, why i can use ts_factory.reserved[0]=12; for example. And i can use this cell. The compiler affect the value with no error. – craken Mar 16 '16 at 13:16
  • In `uint8_t reserved[0]`, the `0` is not the index of the last element, but the size of the array. If you assign `reserved[0] = 12`, you are referring to the element with index `0`. In a _declaration_, the number given is the size of the array, not an index. For example, a declaration `uint8_t a[10]` would have 10 elements, but `a[10]` would be an invalid index since the array is indexed from 0 through 9 (10 elements). – e0k Mar 16 '16 at 13:17
  • If you say that the array don't have any cell and his size is size . HOw can i access on cell with index 0 . It should be compiler error . no ? – craken Mar 16 '16 at 13:21
  • The compiler will not complain if you try to index an array out of the range of memory allocated for it. It will happily perform undefined behaviour. It is your responsibility to make sure you don't access beyond its range. – e0k Mar 16 '16 at 13:21
  • _SO, why i can use ts_factory.reserved[0]=12;_: because in C no out of bounds control is done. `ts_factory.reserved[0]=12` is undefined behaviour. – Jabberwocky Mar 16 '16 at 13:21
  • If this undefined behavior. So, i should see a garbage value if i do ts_factory.reserved[0]=12. But when i do printf is can receive the correct 12 value. More explanation please – craken Mar 16 '16 at 13:25
  • @MarwenBkh "undefined behaviour" means "undefined behaviour", it doesn't mean "displays garbage". – Jabberwocky Mar 16 '16 at 13:27
  • What's mean undefined behavior ? – craken Mar 16 '16 at 13:31
  • @MarwenBkh following may happen: `factory.reserved[0]=12` puts 12 in a memory location that does not belong to your array but belongs to something else. Then you read `factory.reserved[0]` and you find 12, this is very likely to happen, but in the meantime you have overwritten memory that does not belong to the array, which can have all kinds of nasty consequences, but you also may get away with it. You may get away with it on platform A, but you may get a crash on platform B, and may on platform C you get away with it 100 times and the 101th time you get a crash. Google "undefined behaviour". – Jabberwocky Mar 16 '16 at 13:31
  • "you find 12, this is very likely to happen ... ". I run my code many times, and i always find the 12 value ! – craken Mar 16 '16 at 13:36
  • @MarwenBkh sigh... it's **undefined behaviour**. maybe on _your_ platform it works every time by chance, but on another platform it may not work at all or crash the program or.... – Jabberwocky Mar 16 '16 at 13:57
  • OK. I will keep this in mind but not convinced yet. – craken Mar 16 '16 at 14:00
  • 1
    Zero-sized arrays are an obsolete and deprecated gcc extension. The C standard introduced _flexible array members_ with ISO9899:1999 (C99). Use them! – too honest for this site Mar 16 '16 at 14:06

4 Answers4

4

uint8_t reserved[0]; It is an array of size 0

so the sizeof will be zero.

Embedded C
  • 1,448
  • 3
  • 16
  • 29
rabi shaw
  • 441
  • 1
  • 3
  • 14
2

The compiler is correct: you've got an array of size zero (uint8_t reserved[0]) as the only member of your struct, so sizeof gives you zero. Why allocate memory for a zero-sized object?

ForceBru
  • 43,482
  • 10
  • 63
  • 98
2

The compiler is correct as the size of the array is 0, you need to change the size of the array in your code as much you need.
uint8_t reserved[N];
N is size of array you need.

How compiler accepted this: Everything has a unique identity, i.e. a unique address, which implies a non-zero length.It is legal to allocate a zero-sized array. You simply can't do anything useful with it since there is no valid data for you to access.But reserved[0] = 10; is illegal.

Embedded C
  • 1,448
  • 3
  • 16
  • 29
1

It's a gcc extension, and invalid in standard C since 1999.

Look at https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

It was a hack that existed in 1989 standard C, and in earlier (pre-standard) C. Which is probably the reason gcc supports it as an extension.

Peter
  • 35,646
  • 4
  • 32
  • 74