3

I've seen some C code that creates a structure and within the structure there are a number of arrays. Some of those arrays are of size one. So why bother making it an array? Why not just a single int?

I'm talking about something like this:

struct Foo
{

uint8_t Bar[1];
uint32_t BigBar[4];


};

Why not make it just

struct Foo
{

uint8_t Bar;
uint32_t BigBar[4];

};
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
DiBosco
  • 838
  • 8
  • 21
  • 4
    If the array was at the end of the struct it could be a form of [flexible array members](http://stackoverflow.com/q/23093220/1708801) – Shafik Yaghmour Dec 08 '14 at 14:56
  • Maybe this question is already answered here on SO http://stackoverflow.com/questions/6390331/why-use-array-size-1-instead-of-pointer – Ankur Dec 08 '14 at 14:57
  • @Shansingh That is something completely different. – 2501 Dec 08 '14 at 14:59
  • 2
    This might be an interesting question if some context was provided( there might be many reasons why the programmer did that, maybe she/he just liked the style ). Currently it is unanswerable and should be closed. – 2501 Dec 08 '14 at 15:00
  • Seems like it's been answered below, 2501. Not bad for an unanswerable question! ;) – DiBosco Dec 08 '14 at 15:04
  • Is it literally a `1`, or is it hidden behind a `#define` that could easily be changed later? – Degustaf Dec 08 '14 at 15:08
  • It's a 1, it's not any sort of #define. – DiBosco Dec 08 '14 at 15:09
  • @Degustaf a macro must be defined as an identifier and `1` is not. – Jason Hu Dec 08 '14 at 17:29
  • 1
    @HuStmpHrrr I was asking if it was written as `#define ONE 1` and then `uint8_t Bar[ONE];` – Degustaf Dec 08 '14 at 18:23

3 Answers3

3

The answer is that it is good programming habit to do so from two reasons:

  1. In case the programmer decides to change the Bar into an array at some point, there is not a lot of code changing. All needed to be done is to change the constant from 1 to ARRAY_SIZE (it is even better to have the constant defined as one actually)

  2. Using fields which are constructed the same are less prone to mistakes than fields which are different. Thinking programmers are ones who make mistakes :)

Cheers

nerez
  • 437
  • 4
  • 18
1

My guess is for an easier return of a pointer:

it will be easier to return the pointer to the variable:Bar

if you will want to use it as a pointer you would be able to pass Bar instead of &Bar if it was an int

if I had an instance of the struct defined: struct Foo aaa;

you would be able to define:

int *pInt = aaaa.Bar;

instead of:

int *pInt = &(aaaa.Bar);
antonpuz
  • 3,256
  • 4
  • 25
  • 48
  • Then why not use an `uint8_t *`? – Philipp Dec 08 '14 at 14:55
  • 2
    @Philipp, the idea is that an array decays to a pointer I believe. So you can return `foo->Bar` instead of `&foo->Bar`. Whether this is good practice is a separate matter though... – tangrs Dec 08 '14 at 14:55
  • It's not returning a pointer. It's setting a single uint8_t value that is to be sent out. – DiBosco Dec 08 '14 at 14:57
  • However, I take your point about being able to return Foo->Bar, even if it seems like a pretty strange reason, being able to omit an ampersand! ;) – DiBosco Dec 08 '14 at 14:59
1

Consistency with other structs?

struct alien {
    int heads[3];
    ...
};

struct human {
    int heads[1];
    ...
};
potrzebie
  • 1,768
  • 1
  • 12
  • 25