-1

Here is the code I have so far.

I am trying to be able to tell if a certain variable inside a struct is empty. I am going to be creating a struct with some variables being filled and some not and need to know which ones need me to do something and which ones don't.

#include <stdio.h>
#include <stdlib.h>

struct nums {
    int a;
    int b;
    int c;
    int d;
} typedef numbers;

int main() {
    numbers bob;

    bob.a = 69;

    if (bob.b == NULL) {
        printf("no number stored in b");
    }
    return 0;
}

but I just get the error

warning: comparison between pointer and integer

Any ideas?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    A variable in C cannot be 'empty'. In your example, the value never has been set so it is *undefined* - it van be anything. – Jongware Feb 14 '16 at 01:05
  • At the cost of some overhead you could have add a bit-field member to the struct treating it as a collection of flags where bit i is set to 1 if and only if the ith struct member has been set. In addition to the memory overhead that is entailed you would need to properly initialize it and make sure that it is updated as needed. – John Coleman Feb 14 '16 at 01:15
  • Any ideas...regarding the error? The warning message itself is quite clear: you're comparing an integer (bob.b) with a pointer (NULL). In case you have a SQL background... Please note C-NULL has nothing to do with SQL-NULL – mauro Feb 14 '16 at 01:27
  • 3
    This is a very awkward way to use `typedef`. It is not strictly incorrect, but highly unusual and most programmers will be wondering why you code even compiles. – chqrlie Feb 14 '16 at 02:04

2 Answers2

4

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);  
}
pablo1977
  • 4,281
  • 1
  • 15
  • 41
  • 1
    Regarding your 1st approach, there is no difference from INT_MIN and zero - these are all valid values, and so user has to make the assumption that either number is never used. – artm Feb 14 '16 at 01:37
1

Usually there is no way to tell if you have actually stored something in an int variable.

In your case, though, you could:

  • Initialize your struct: numbers bob = { 0 }; // <-- this makes a, b, c, d equal to zero
  • Then check if you have any number different than 0:

    if(bob.b == 0){
            printf("no non-zero number stored in b");
    }
    
artm
  • 17,291
  • 6
  • 38
  • 54
  • .. But of course 0 is a valid integer so it is "not empty" or is it? Perhaps INT_MAX would be a better choice – Ed Heal Feb 14 '16 at 01:10
  • @EdHeal - you're right. This is just a suggestion for him to check if he actually stores something different than 0 in his struct. I did not mention 0 as "empty" or "no-filled" – artm Feb 14 '16 at 01:12
  • 2
    Your solution seems to assign a special meaning to zero. Why not `if(bob.b == 23) { printf("no non-twentythree number stored in b");}` ? OP should understand that you cannot say if a variable was set or not by just looking the variable content. – mauro Feb 14 '16 at 01:25
  • @mauro - it depends on the context that a zero can have a special meaning. I did mention that "Usually there is no way to tell if you have actually stored something in an int variable." – artm Feb 14 '16 at 01:31
  • @mauro I can see your point, but your example is an exaggeration. Of course, if you have number 23 there then it must have been assigned explicitly. Number zero is the default value when you initialize `numbers bob = {};` – artm Feb 14 '16 at 01:34
  • @artm but one could have executed `bob.b=0;` right before your if. Anyhow... I think we have understood each other's point. – mauro Feb 14 '16 at 01:46
  • @chqrlie - agree, the empty braces {} are C++ standard, C requires {0}. I'm editing this - thanks. – artm Feb 14 '16 at 02:27
  • {} vs {0} - http://stackoverflow.com/questions/1352370/c-static-array-initialization-how-verbose-do-i-need-to-be/1352379#1352379 and, http://stackoverflow.com/questions/3003574/explicit-initialization-of-struct-class-members – artm Feb 14 '16 at 02:28