Expression must have a pointer to object type in C
Categories:
Understanding 'Expression must have a pointer to object type' in C

Demystify the common C compiler error 'expression must have a pointer to object type' and learn how to correctly use pointers, arrays, and structs.
The error message "expression must have a pointer to object type" is a common hurdle for C programmers, especially those new to pointers. This error typically arises when you attempt to dereference a variable that the compiler doesn't recognize as a pointer to an object type. In C, dereferencing (using the *
operator) is only valid on expressions that evaluate to a pointer type. This article will break down the common causes of this error and provide clear solutions.
What Does 'Pointer to Object Type' Mean?
In C, an "object type" refers to any data type that is not a function type or an incomplete type (like void
before it's cast). This includes int
, char
, float
, struct
types, union
types, and arrays. A "pointer to object type" is simply a variable that stores the memory address of such an object. When you use the dereference operator *
on a pointer, you are telling the compiler to access the value stored at the memory address held by that pointer.

Visualizing pointers and object types in memory.
Common Causes and Solutions
This error most frequently occurs in a few specific scenarios. Understanding these will help you quickly diagnose and fix the problem.
1. Dereferencing Non-Pointer Variables
The most straightforward cause is trying to dereference a variable that is not a pointer at all. This often happens due to a misunderstanding of how arrays or simple variables work.
int myInt = 10;
// This will cause the error: 'expression must have a pointer to object type'
// because myInt is an int, not a pointer.
// int value = *myInt;
// Correct way to access the value of myInt:
int value = myInt;
// If you intended to use a pointer:
int *ptrToInt = &myInt;
int dereferencedValue = *ptrToInt;
Incorrectly dereferencing a non-pointer variable.
*
operator is for dereferencing pointers, and the &
operator is for getting the address of a variable (creating a pointer).2. Incorrect Array Indexing vs. Pointer Dereferencing
Arrays in C often decay into pointers to their first element. However, accessing array elements uses the []
operator, not *
directly on the array name (unless you're doing pointer arithmetic).
int myArray[5] = {1, 2, 3, 4, 5};
// This will cause the error: 'expression must have a pointer to object type'
// because myArray[0] is an int, not a pointer.
// int val = *myArray[0];
// Correct way to access an array element:
int val = myArray[0];
// Correct way to dereference a pointer to an array element:
int *ptrToArrayElement = &myArray[0];
int firstElement = *ptrToArrayElement;
// Or, using pointer arithmetic on the array (which decays to a pointer):
int anotherFirstElement = *myArray; // myArray decays to &myArray[0]
int secondElement = *(myArray + 1); // myArray + 1 points to myArray[1]
Confusing array indexing with pointer dereferencing.
3. Dereferencing void*
Without Casting
A void*
pointer is a generic pointer that can point to any data type, but it cannot be directly dereferenced because the compiler doesn't know the size or type of the object it points to. You must cast it to a specific pointer type before dereferencing.
int x = 100;
void *genericPtr = &x;
// This will cause the error: 'expression must have a pointer to object type'
// because genericPtr is a void*.
// int value = *genericPtr;
// Correct way: Cast to the appropriate pointer type first
int value = *( (int*)genericPtr );
// Example with malloc, which returns void*
// int *dynamicInt = (int*)malloc(sizeof(int));
// if (dynamicInt != NULL) {
// *dynamicInt = 50;
// printf("Dynamic int: %d\n", *dynamicInt);
// free(dynamicInt);
// }
Dereferencing void*
without an explicit cast.
4. Incorrect Use of ->
vs. .
Operators with Structs/Unions
When working with struct
or union
types, you use the .
operator for direct access to members if you have the struct variable itself. If you have a pointer to a struct, you must use the ->
operator (or dereference the pointer first with *
and then use .
).
typedef struct {
int id;
char name[20];
} Person;
Person p1;
p1.id = 1;
Person *ptrToP1 = &p1;
// This will cause the error: 'expression must have a pointer to object type'
// because p1.id is an int, not a pointer.
// int someId = *p1.id;
// Correct way to access member of a struct variable:
int directId = p1.id;
// Correct way to access member of a struct via a pointer:
int ptrId = ptrToP1->id;
// Equivalent to: int ptrId = (*ptrToP1).id;
Misusing dereference operator with struct members.
&
when assigning it to a pointer.Debugging Strategy
When you encounter this error, follow these steps:
- Locate the line: The compiler message will point to the exact line where the error occurs.
- Identify the expression: Look at the expression immediately following the
*
operator. - Check its type: Determine the data type of that expression. Is it actually a pointer? If not, that's your problem.
- Review intent: What were you trying to achieve? Were you trying to get the value of a variable, access an array element, or access a struct member? Adjust your code accordingly using
&
,[]
,.
, or->
as needed.