ProgrammingEmbedded Developer, Low-level Programmer

Describe the features of working with different types of type casting in C. What is the difference between implicit and explicit type casting, what dangers are associated with accessing memory through a cast pointer, and what are the rules for safe casting?

Pass interviews with Hintsage AI assistant

Answer.

Background: The C language has always been flexible regarding type conversions to facilitate work with low-level memory and various platforms. However, its conciseness and power can easily lead to vulnerabilities and defects related to incorrect type casting, especially when dealing with pointers and bitwise arithmetic.

Issue:

  • Implicit (automatic) conversions are performed by the compiler according to standard rules, sometimes resulting in data loss.
  • Explicit (manual, "cast") conversions ignore compiler warnings, which may lead to accessing memory of incorrect size or structure.
  • When casting between incompatible types, especially between pointers, crashes, memory corruption, or "undefined behavior" may occur.

Solution:

  • Use explicit casts only in strictly controlled situations, fully understanding the matching of type representations.
  • Avoid casting between pointers of fundamentally different types unnecessarily.

Example code:

#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Value: %d\n", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // Accessing raw memory: allowed if ptr actually points to int

Key features:

  • Implicit casts are convenient but can be a source of data loss.
  • Explicit casts shift responsibility to the programmer.
  • Casting pointers to structures of different sizes is dangerous.

Tricky Questions.

1. When is it permissible to cast void to a pointer to a structure, and is it always safe?*

Such casting is safe if the address indeed points to an instance of the given structure; otherwise, the behavior is undefined.

2. What happens if you cast a pointer to a structure of one length to a pointer to a structure with fewer or more fields?

Accessing the fields of the "new" structure will lead to reading/writing beyond the bounds of the original structure, potentially corrupting data.

Example code:

typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b — accessing "garbage"

3. Is it safe to cast a pointer to int to a pointer to char to access the bytes of this number?

This is one of the typical techniques for memory manipulation — byte access is permissible but requires caution, as alignment issues may arise and byte order depends on the architecture (big-endian/little-endian).

Common mistakes and anti-patterns

  • Incorrectly casting pointers to different structures.
  • Implicit type conversions that lead to a loss of significance (e.g., assigning double to int).
  • Using casts as a "quick way" to work with data without checking consistency.

Real-life Example

A junior programmer attempted to optimize access time by processing a network packet, casting a pointer from a raw array to a pointer to a data structure with fields of different types.

Pros:

  • The code seemed fast and concise.

Cons:

  • On a new platform, the structure turned out to be packed differently, and the casting led to memory corruption.

After rework, each byte of the packet was extracted manually via memcpy.

Pros:

  • Functionality on all platforms, eliminating dependencies on alignment.

Cons:

  • It became slightly slower and longer, but more reliable.