liveBook · Manning

Effective type

As explained in Modern C

An effective type is the C type through which an object is permitted to be accessed under the language's object-access rules.

Consider an allocated byte array: casting its address to unsigned* is permitted as a conversion, but reading through *p violates the effective-type rule. TAKEAWAY: Objects must be accessed through their effective type or through a pointer to a character type. section 12.6

The core access rules are:

  • A variable or compound literal has the effective type specified by its declaration and cannot be accessed through an unrelated non-character type. section 12.6
  • Any object may be viewed through a character type, but an unsigned-char array cannot be read through another type. section 12.6
  • A union object's effective type is the union type; accessing a member is allowed when its byte representation forms a valid value of the access type. section 12.6
  • Allocated storage begins uninitialized and typeless; assignments to its elements provide effective types and values. section 13.1

A cast does not authorize access

unsigned char A[sizeof(unsigned)] = { 9 }; unsigned* p = (unsigned*)A; printf("value %u\n", *p); // invalid access The cast creates an unsigned* value, but A remains an unsigned-char array. Dereferencing p accesses the bytes through neither the effective type nor a character type, leaving the program state undefined. section 12.6

   unsigned char A[sizeof(unsigned)] = { 9 };
   // Valid but useless, as most casts are
   unsigned* p = (unsigned*)A;
   // Error: access with a type that is neither the effective type nor a
   // character type
   printf("value \%u\n", *p);


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":16}],[{\"line\":0,\"ch\":19},{\"line\":0,\"ch\":25}],[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":11}],[{\"line\":2,\"ch\":3},{\"line\":2,\"ch\":11}],[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":11}],[{\"line\":2,\"ch\":3},{\"line\":2,\"ch\":11}],[{\"line\":0,\"ch\":3},{\"line\":0,\"ch\":11}],[{\"line\":2,\"ch\":3},{\"line\":2,\"ch\":11}],[{\"line\":5,\"ch\":3},{\"line\":5,\"ch\":9}]]"}
!@%STYLE%@!

Inspect the complete example showing a valid pointer conversion followed by an invalid dereference. section 12.6

How Modern C covers it

How deep it goes
Defines declared, union, character, and allocated-storage cases, but defers the latter's detailed treatment.
Examples
Uses an unsigned-char array cast to unsigned* and allocated storage initialized through assignment.
What it assumes
Assumes pointers, casts, objects, and unions while grounding their access consequences in C's memory model.
What you can do after
Evaluate pointer-based accesses for effective-type violations and recognize when dereferencing leaves program state undefined.
How it connects
Ties effective type to pointers, casts, object representation, unions, aliasing, and malloc.

Also explained in

Compare how 2 books explain effective type →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C. The section links point to the parts of the book it draws on.