Ternary Operator (?:) based assignment avoids type check in C

The type of the expression (b >= 8) ? array : malloc(8) is void* (because malloc(8) has the type void*). You can see this by doing something non-sensical and having the compiler tell you:

((b >= 8) ? array : malloc(8)) * 5;
<source>:10:36: error: invalid operands to binary * (have 'void *' and 'int')
   10 |     ((b >= 8) ? array : malloc(8)) * 5;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
      |                       |
      |                       void *

void* can be implicitly converted to a pointer of any type, which is why the compiler doesn't complain when you assign that value to a.


From the C Standard (6.5.15 Conditional operator)

  1. ... otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.

The function malloc returns a pointer of the type void *. So the type of the expression with the conditional operator is void *. And a pointer of the type void * can be assigned to a pointer of any other object type.

From the C Standard (6.3.2.3 Pointers)

1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

In fact you have

a = ( void * )(b >= 8 ? array : malloc(8) );