Possible side effects of executing a typedef structure for an array of a single element in C

I came across this code.

typedef __mpz_struct MP_INT; typedef __mpz_struct mpz_t[1]; 

Here struct __mpz_struct is a structure that is typed into an array of one element. I understand that this is a trick for passing by reference in C. Then mpz_t used as a type for declaring variables and passing them functions as parameters. In addition, there was another comment

 /* MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects of single-element arrays mp*_t */ 

What side effects are they talking about?

+6
source share
4 answers

Passing an array to a function allows the array to decay into a pointer to its 1st element.

You can achieve the same effect by applying the Address-Of & operator to a simple variable of the same type as the elements of the array.

Examples:

 struct S { int i; float f; }; 

it

 void set_S(struct S * ps) { ps->i = 40; ps->f = 2.; } 

equivalently

 void set_S(struct S ps[1]) { ps->i = 40; ps->f = 2.; } 

equivalently

 void set_S(struct S * ps) { ps[0].i = 40; ps[0].f = 2.; } 

equivalently

 void set_S(struct S ps[1]) { ps[0].i = 40; ps[0].f = 2.; } 

Singleton Array:

 typedef struct S Array_of_S_with_size_1[1]; int main(void) { Array_of_S_with_size_1 array_of_S_with_size_1; array_of_S_with_size_1[0].i = 0; array_of_S_with_size_1[0].f = 0.; set_S(array_of_S_with_size_1); ... } 

The above main() provides the same functions as:

 int main(void) { struct S s; si = 0; sf = 0.; set_S(&s); ... } 

I do not see any benefit using the "One element-array" approach. An exception may be if the & button is broken on one keyboard ...; -)

+2
source

I see two parts of your question. The first part of how typedef works to pass arguments to functions is best illustrated with an example. Without this, I have to guess a little.

In C function declarations , an array parameter is equivalent to a pointer . That's why you see (for example) an equivalent core function,

 int main(int argc, char **argv) 

and

 int main(int argc, char *argv[]) 

Similarly, if a function in your program is declared

 int func(__mpz_struct *arg) 

he would be equivalent

 int func(__mpz_struct arg[]) 

and therefore to

 int func(mpz_t arg) 

In addition, on the call side, if you have a variable of type mpz_t, therefore an array, and you pass it to a function, " pointer evasion " takes effect: in an expression, if you use an (name) array, it "splits" into a pointer on your first item. This way you can call the function:

 mpz_t value; func(value); 

Of course, in order to modify these mpz_t objects outside of the API functions, you still need to know about their true nature.

The side effects that you are talking about, I would also have to guess about them. Perhaps this means that you should know that you are working with pointers inside functions. We can assume that it is better to make this explicit using pointer syntax.

+2
source

You can assign MP_INT to another, but you cannot assign mpz_t to another, because the assignment to arrays is undefined. If you don’t want your clients to assign variables other than your methods (which could do memory management, etc.), this is the trick for you.

+1
source

Take a look at this sample code.

 typedef char type24[3]; 

Same as yours, but the well-known char data type introduced in your struct __mpz_struct type.

the type def above means I use the typedef above to represent char [3].

So in your code example

 typedef __mpz_struct mpz_t[1]; 

mpz_t must be __mpz_struct .

0
source

Source: https://habr.com/ru/post/987996/


All Articles