Max
Max

Reputation: 15955

What does the (*) in (int (*)[30]) mean?

What does (int (*)[30]) mean in C? For instance, in:

int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20]));

Upvotes: 6

Views: 15759

Answers (6)

John Bode
John Bode

Reputation: 123458

int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20]));

Breaking it down:

      b        -- b
    (*b)       -- is a pointer
    (*b)[30]   -- to a 30-element array
int (*b)[30]   -- of int.

In both declarations and expressions, postfix operators like [] have higher precedence than unary operators like *, so T *a[] is interpreted as T *(a[]); IOW, a is an array of pointer to T. To designate a as a pointer to an array, we have to force the grouping T (*a)[].

Simlilarly, the cast expression (int (*) [30]) means "treat the pointer value returned by malloc as a pointer to a 30-element array of int". Note that, technically speaking, the cast expression is superfluous and should be removed.

The malloc call itself seems very wrong. You're allocating 30 instances of a 20-element array of int, but assigning the result to a pointer to a 30-element array of int; that's going to cause problems. Assuming you're trying to allocate a N x 30 matrix of int, the following would be safer:

int (*b)[30] = malloc(N * sizeof *b); 

The type of the expression *b is int [30], so sizeof *b is the same as sizeof (int [30]).

Upvotes: 3

Carl Norum
Carl Norum

Reputation: 224904

You can use cdecl to figure these kinds of things out:

cdecl> explain (int (*) [30]) 
cast unknown_name into pointer to array 30 of int

Upvotes: 2

FatalError
FatalError

Reputation: 54551

There's really nothing special about (*). Since you're just referencing a type in your typecast (and not a variable, which has a name, of that type), you simply omit the name. Here the parens are still needed to distinguish an array of pointers from a pointer to an array.

Upvotes: 0

ephemient
ephemient

Reputation: 204718

How to parse C declarations and types: unwind them from outside in.

  • int (*b)[30].
  • (*b)[30] is an int.
  • (*b) is an int array of length 30.
  • b is a pointer to an int array of length 30.

The nameless version int (*) [30] is entirely identical, just the name has been omitted.

If you have a copy of The C Programming Language, there's a program in there called cdecl that can transform such declarations into English. There's been various modifications of it over time, for example cutils in Debian supports the nameless form, and cdecl.org is online.

Upvotes: 2

Charles Cavalcante
Charles Cavalcante

Reputation: 1608

(*) before a variable name means that is a POINTER.

We have just seen that a variable which stores a reference to another variable is called a pointer. Pointers are said to "point to" the variable whose reference they store.

Using a pointer we can directly access the value stored in the variable which it points to. To do this, we simply have to precede the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value pointed by".

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182763

It means, roughly, "is a pointer".

int (*b)[30]

This means "b is a pointer to an array of 30 integers".

(int (*) [30])

This means "cast to a pointer to an array of 30 integers".

Upvotes: 14

Related Questions