49

Is there a way to check if a variable has been initialized or not in C?

Consider the following example,

int main(){
    int a = 3, b = 7, c;

    if ( a > b )
        c = a-b;

    // Now, how can I check if the variable "c" has some value or not
    // I don't want check like this,
    // if ( isalpha(c) ) or if ( isdigit(c) )
    // or anything similar to like that
}

In other words, does C has some function like defined in Perl. In Perl, I can simply do if (defined c)that would check if the variable is defined or not, and it'd return False for above example. How can I achieve the same in C?

rohithpr
  • 6,050
  • 8
  • 36
  • 60
Hafiz Temuri
  • 3,882
  • 6
  • 41
  • 66
  • 8
    @nullpointer: That doesn't work; it's just undefined behavior. – user2357112 Apr 08 '16 at 03:28
  • `if(c)` will just test whether `c` evaluates to `true` or `1`. So if `c` is not defined then `c` will evaluate to its default value which will probably return `false`. – Sohan Shirodkar Apr 08 '16 at 03:35
  • 6
    @SohanShirodkar: `c` does not have a default value. It's initial value is __unspecified__. Reading it would cause __undefined behavior__. – Bill Lynch Apr 08 '16 at 03:36
  • Yes, absolutely correct. This will result in undefined behavior. But, C assigns default value to its variables based on their storage classes. By default any local variable belongs to `auto` storage class, which is not assigned a special default value as such(we call this `garbage value` if I am not wrong). – Sohan Shirodkar Apr 08 '16 at 03:39
  • 3
    @BillLynch where you said "unspecified" should read "indeterminate" – M.M Apr 08 '16 at 04:14
  • 4
    In C, we would say that your variable `c` is **defined** as an integer, but it is **uninitialized** when `b < a`. If a variable isn't defined and you try to reference it, the compiler will generate an error (the variable does not exist). In some cases, the compiler may warn you if you reference a variable before you've assigned a value to it. But short of the methods referred to in the accepted answer, you don't have a run-time method to check if you've assigned a value. – tomlogic Apr 08 '16 at 05:27
  • 2
    "defined" means memory is allocated for the variable. When you use `int c;`, `c` is both *declared* and *defined*. – Spikatrix Apr 08 '16 at 05:38
  • In c++, there is an [experimental library](http://en.cppreference.com/w/cpp/experimental/optional) that allows you to define optional variables, which would allow you to check whether the variable has been initialized. I'm not providing this as an answer because it assumes (a) you'd be willing to move from c to c++, (b) that you're using a compiler that has implemented this library, and (c) that you're willing/allowed to use experimental features--which is a lot of (big) `if`s. I hope it could be interesting nonetheless. – sudo make install Apr 08 '16 at 10:51
  • A good compiler would tell you if you attempted to use `c` before it has been assigned a value. – Alnitak Apr 08 '16 at 15:51

3 Answers3

79

C does not have this ability. You have two main options:

A sentinel value

For example, if you know that the value of c will never be negative, then initialize it to -1, and test that for that.

Add another variable

Create another variable bool we_set_c_to_something = false; and then set it to true when you write to c.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
11

C is a compiled language which doesn't support runtime variable binding, while Perl is a interpreted language which support dynamic typing. So you can check the definition of a variable in Perl, but not in C.

When you declare a variable in C int c;, this variable c is defined but without initialization. The declaration and definition are in one statement.

The definition of a variable in C is not checked by code writer. The compilers do it for you. When compile and link your C code, the compiler will check all variable's definitions. An error will be invoked and the compiling or linking process will stop if there are undefined variables found in your code.

Hope this will make you distinguish the differences.

alijandro
  • 11,627
  • 2
  • 58
  • 74
  • I think parts of this are a bit imprecise. AFAIK dynamic _typing_ isn't really the thing that allows undefined variables to be referenced in Perl, although I'm not sure what the actual name of the feature is. Also, when you say a compiler/linker fails with an error if there are undefined variables, when you say "undefined" I suppose you mean _undeclared_, not _uninitialized_? (Compilers generally _don't_ stop for uninitialized variables unless explicitly asked to.) – David Z Apr 08 '16 at 08:18
  • @DavidZ When I said `undefined`, it's undefined. e.g only one statement `extern int a;`, I can use a in my C code. It's declared, but not defined. There is an error at linking, but no error when compiling. – alijandro Apr 08 '16 at 08:38
  • Ah, I see what you mean. Sorry, I misunderstood that. It might clarify things to mention `extern` in your answer as an (or, the) example of how a variable can be declared but not defined. – David Z Apr 08 '16 at 08:47
  • Dynamic reference binding, probably. – Benjamin Gruenbaum Apr 08 '16 at 09:40
10

Wrong question. You're not asking whether the variable is defined. If the variable is not defined then compilation fails. Look up the difference between "declaration" and "definition". In the case of those local variables, you have defined the variable c.

What you're looking for is initialisation. Many compilers will warn you about using variables before they're initialised, but if you persist in running that code then the assumption is that you know better than the compiler. And at that point it's your problem. :) Some languages (e.g. Perl) have an extra flag that travels along with a variable to say whether it's been initialised or not, and they hide from you that there's this extra flag hanging around which you may or may not need. If you want this in C, you need to code it yourself.

Since C++ allows operator overloading, it's relatively easily to implement this in C++. Boost provides an "optional" template which does it, or you could roll your own if you want a coding exercise. C doesn't have the concept of operator overloading though (hell, the concept didn't really exist, and the compilers of the day probably couldn't have supported it anyway) so you get what you get.

Perl is a special case because it rolls the two together, but C doesn't. It's entirely possible in C to have variables which are defined but not initialised. Indeed there are a lot of cases where we want that to be the case, particularly when you start doing low-level access to memory for drivers and stuff like that.

Graham
  • 1,655
  • 9
  • 19
  • 6
    This question is about C not C++. – 2501 Apr 08 '16 at 09:41
  • 3
    @2501 True, but since most C compilers are also C++ compilers, it seemed worth mentioning as an aside. Many people write C-like code in C++ anyway because they like some of the extra features. It also gave me a hook to illustrate why it can't be added to standard C. – Graham Apr 08 '16 at 12:24