Why declare a struct that only contains an array in C?
Asked Answered
D

7

135

I came across some code containing the following:

struct ABC {
    unsigned long array[MAX];
} abc;

When does it make sense to use a declaration like this?

Disturbance answered 6/8, 2011 at 11:43 Comment(0)
R
188

It allows you to pass the array to a function by value, or get it returned by value from a function.

Structs can be passed by value, unlike arrays which decay to a pointer in these contexts.

Revolutionist answered 6/8, 2011 at 11:45 Comment(1)
Beware of doing this with arrays, more than say 16 or 32 bytes, for functions that don't inline: it's more efficient to pass them by const-reference, unless the callee already needs a tmp copy it can destroy. If the call / return don't optimize away, a medium to large array (thousands of bytes) is a terrible thing to pass by value.Shanaeshanahan
D
86

Another advantage is that it abstracts away the size so you don't have to use [MAX] all over your code wherever you declare such an object. This could also be achieved with

typedef char ABC[MAX];

but then you have a much bigger problem: you have to be aware that ABC is an array type (even though you can't see this when you declare variables of type ABC) or else you'll get stung by the fact that ABC will mean something different in a function argument list versus in a variable declaration/definition.

One more advantage is that the struct allows you to later add more elements if you need to, without having to rewrite lots of code.

Distiller answered 6/8, 2011 at 12:36 Comment(0)
A
46

You can copy a struct and return a struct from a function.

You cannot do that with an array - unless it is part of a struct!

Antipode answered 6/8, 2011 at 11:45 Comment(0)
D
27

You can copy it like this.

struct ABC a, b;
........
a = b;

For an array you would need to use memcpy function or a loop to assign each element.

Dyspepsia answered 6/8, 2011 at 11:49 Comment(2)
(so it allows cleaner code - it won't make any difference in speed etc)Errolerroll
That's useful. Unfortunately you can't do if (a == b)!?! how inconsistent that is. For C++ it looks for an == operator. In C it says "invalid operands to binary ==".Payload
D
12

You can use struct to make a new type of data like string. you can define :

struct String {
    char Char[MAX];
};

or you can create a List of data that you can use it by argument of functions or return it in your methods. The struct is more flexible than an array, because it can support some operators like = and you can define some methods in it.

Hope it is useful for you :)

Dorie answered 6/8, 2011 at 18:45 Comment(5)
Basically, it's the closest thing C has to creating a class. I like this answer because it comes the closest to pointing that out.Hubbell
No such thing as a method in C. structs in C are plain old data. It has an = operator supported by default (which the other answers show is the reason to do this), but this is misleading and mostly applies to C++, not C.Schlesinger
@J Sternberg: "Method" is just a way of thinking about subroutines as being related to the data "objects" that they affect. You can certainly create "classes" of "objects" and "methods" that operate on them in C. The language just doesn't formally define such things. If you want to create better abstractions in C, stuffing things into a struct is usually the best way to do it.Hubbell
In addition, if you really wanted to "create" methods in C, you could use function pointers (yes, yes, tricky syntax, no data protection, etc) to associate functions with the data that they operate on. You have to pass in "self" in the first argument (you could even name it "this", if you wanted), since there's no automatic creation of this pointer inside the function in C. Of course, it's all gymnastics, you get things like this by default in C++, though it's true there could be hidden overhead as a bonus...Shoulders
@NateC-K a struct is just a struct and there is no need to call a function that operates on a struct 'method'. In this context 'class' is a bit misleading. For really the point of packing the array into a struct is making it copyable. On the contrary methods take their 'this' class as reference. Also the whole class/method-lingo makes more sense in conjuction with type-class polymorphism, which doesn't really exist in cChavarria
O
4

Another advantage of using such a struct is that it enforces type-safety wherever such a struct is used; especially if you have two types consisting of arrays of the same size used for different purposes, these types will help you avoid accidentally using an array inappropriately.

If you do not wrap an array in a struct, you can still declare a typedef for it: this has some of the advantages of the struct – • the type is declared once, • the size is automatically correct, • the intent of code becomes clearer, • and code is more maintainable – but you lose ◦ strict type-safety, ◦ the ability to copy and return values of the type and ◦ the ability to add members later without breaking the rest of your code. Two typedefs for bare arrays of a given type only yield different types if they are of different sizes. Moreover, if you use the typedef without * in a function argument, it is equivalent to char *, drastically reducing type-safety.

In summary:

typedef struct A_s_s { char m[113]; } A_s_t; // Full type safey, assignable
typedef char   A_c_t[113];                   // Partial type-safety, not assignable

A_s_t          v_s(void);     // Allowed
A_c_t          v_c(void);     // Forbidden

void           s__v(A_s_t);     // Type-safe, pass by value
void           sP_v(A_s_t *);   // Type-safe
void           c__v(A_c_t);     // UNSAFE, just means char * (GRRR!)
void           cP_v(A_c_t *);   // SEMI-safe, accepts any array of 113
Overawe answered 16/8, 2015 at 11:58 Comment(0)
S
2

A structure can contain array initialization, copy and fini functions emulating some of the advantages of the OOP memory management paradigms. In fact, it's very easy to extend this concept to write a generic memory management utility (by using sizeof() structure to know exactly how many bytes are being managed) to manage any user defined structure. Many of the smart production code bases written in C use these heavily and typically never use an array unless its scope is very local.

In fact for an array embedded in a structure, you could do other "smart things" such as bound checking anytime you wanted to access this array. Again, unless the array scope is very limited, it is a bad idea to use it and pass around information across programs. Sooner or later, you will run into bugs that will keep you awake at nights and ruin your weekends.

Stedt answered 4/2, 2014 at 13:49 Comment(1)
This does not answer the question why one might use a struct containing only an array.Overawe

© 2022 - 2024 — McMap. All rights reserved.