Home > Software design >  Why we need to declare variable data type before assigning a return value from a function in C?
Why we need to declare variable data type before assigning a return value from a function in C?

Time:12-08

I am new to C. Suppose we have a function get_float(); it should return a float value. but in C, we should explicitly declare a float type variable first before we assign the float value to it.

float number = get_float("what's the number");

I was wondering any reasons for designing such rule.

It seems to decrease mistakes if we can declare a variable without declaring its data type in the case of assigning function return value. Programmers don't need to worry that they declare a wrong data types that don't match with the function return value.

number = get_float("what's the number");

CodePudding user response:

You're right that forcing the programmer to provide a type for each variable means a little more work for the programmer. But this is designed to reduce the possibility for error, and in most cases, it does.

You brought up the example

float number = get_float("what's the number");

and you compared it with the "simpler"

number = get_float("what's the number");

and you wrote "Programmers don't need to worry that they declare a wrong data types that don't match with the function return value."

But here you're assuming that the only mistake a programmer might make is picking the wrong type for the variable. You're assuming that the expression the programmer writes on the right-hand sign of the = is always correct, so it would always be correct for the compiler to just guess a type for the variable based on the type on the right-hand side. But that's not necessarily true. There are lots of different errors that programmers can make. And trying to guess the programmer's intent when the programmer starts making mistakes can be an arbitrarily tricky process.

For example, suppose a careless programmer believed that the fgets function returned the length of the line it had just read. Suppose this programmer wrote

line = fgets(stdin);
if(line == 0)
     printf("empty line\n");
else printf("you typed %d characters\n");

This code is obviously pretty wrong. But if the compiler picked a type for the programmer's line variable, the type it would pick would be char *, which would not be what the programmer wanted. Moreover, by chance, the program would almost seem to work, because the test if(line == 0) would test to see whether fgets returned a null pointer, which is how it indicates an error. So there wouldn't be a compiler warning on that line, either. The line printf("you typed %d characters\n") would print a very strange result, but depending on the compiler, it might not generate a warning, either. (Some compilers warn when you try to print a pointer using %d, but some don't.)

Forcing the programmer to explicitly pick a type for every variable, as C does, is not to make things easy on the programmer in the shortest term. It's supposed to be better in the long term.

Yes, it's more work to have to pick the type of every variable up-front, and yes, it might seem easier if the compiler could guess the right type at least some of tie time. Yes, the errors when you forget to declare a variable, or when you declare it with the wrong type, force you to go back and figure things out and fix things up, when it might seem easier for the compiler to fix them up for you or something.

But the bottom line is that forcing you to pick a type for every variable does, sooner or later, catch a lot of errors. Forcing you to pick a type for every variable introduces a useful form of redundancy, and just like in human languages, redundancy helps eliminate an important class of mistakes.

Of course, forcing you to pick a type for every variable isn't the only possible strategy. There are successful languages that don't force you to pick — but C simply isn't one of them.

CodePudding user response:

There are languages which are not strictly typed as Python for example. The reason for a strictly typed language is that it will make it easier to know what a variable is of.

For example, in Python you could have a function:

def foo(number): 
    if number == 1:
        return "This is a string"
    else: 
        return 200

This function will return two different values and valuetypes. This would mean that the return value have to be handled of the caller of the function which may create a lot of troubles.

The same goes for variables within classes, what you believe may be assigned to a variable in Python you have to double check that it contains what you believe when in a strictly typed language you'll always have a stric ttype of the variable.

In a way, as in your example, the typing check is done when assigning your variable to a float. Even the IDE or the compiler will tell you that the function may not return a float value and therefore should not compile/be run.

CodePudding user response:

The main reason why name = ... won't work in this fashion is the scope of the variables. Imagine a case:

int name; // global variable
int main() {
   name = 1;
}

Should the name refer to the global variable or rather to the a newly create local variable?

There is a need for distinction between a variable declaration (even if the type is automatically deducted) and the assignment.

This problem appeared in B programming language, the grand-pa of C, grand-grand-pa of C and other offspring.

The issue was solved by marking that an expression is actually a declaration with initializers by adding auto keyword.

auto name = 42;

Note that B supported only a single type, a cpu register which was more-or-less equivalent of int.

With advent of C a new typing system was introduced forcing to place a type before the variable to mark the declaration.

int name = 42;

However to keep existing B code the keyword auto and implicit int type rule was added.

C kept the C syntax, and auto as a reserved keyword. From C 11 the auto is used for declaration with a type automatically deducted from the type of the initializer. There is some chance that this feature will be added to upcomming C23 standard. See proposal.

On the other hand, Python took the other approach where an assignment creates a new variable but now developers are forced to use global or nonlocal statements to bound the scope of the variable.

  • Related