What you are trying to do has not sense in C.
The only solution is to analyze your code and to proof, with a logical analysis, that certain variable is used (or not).  
I'll give two ideas that can help you, anyway.  
1. INITIALIZATION TO DUMMY VALUE 
One could choose a value in the range of the type of the variable that we know that it has not a meaning among the values that our program handle.
For example, for the int type one could choose INT_MIN as such a dummy value.
It's the most negative value that the int type can hold.
In 32-bit 2's complement ints this value is -2147483648, which is probably your case.
[INT_MAX is defined in <limits.h>, so you have to #include it.]  
#include <limits.h>
numbers bob = { INT_MIN, INT_MIN, INT_MIN, INT_MIN};  
if (bob.b == INT_MIN) puts("Unused object.");  
This method works, provided that you never have INT_MIN as a valid value in the rest of your program.  
2. CHANGE YOUR APPROACH 
Instead of using int, one could use a pointer to an int:  
#include <stdio.h>
#include <stdlib.h>
typedef struct { int *a, *b, *c, *d; } pnumbers;  
int main(void) {
  pnumbers bob = { NULL, NULL, NULL, NULL };  
  int val = 32;  
  bob.a = &val;
  bob.c = malloc(sizeof(int));
  bob->c = 20;
  if (bob.a != NULL) printf("%d\n", bob->a);  
  if (bob.b == NULL) puts("Unused member");  
  if (bob.c != NULL) printf("%d\n", bob->c);  
}