6

Consider the following quote from the C book by Kernighan & Ritchie

All variables must be declared before use, although certain declarations can be made implicitly by context.

It is known that all variables of any type must be declared before using it further. I am unaware with the latter part of the statement that certain declarations can be made implicitly by context.

In C, in general, the variables fall under four basic data types char, int, float, double. How can a variable from these datatypes can be used without any declaration before. Please provide an example that shows implicit declaration based on content the variable holds.

Lover of Structure
  • 1,561
  • 3
  • 11
  • 27
hanugm
  • 1,127
  • 3
  • 13
  • 44
  • 3
    It's possible it's referring to things like int a[] = {1,2,3}; – Oliver Charlesworth May 28 '17 at 10:30
  • 6
    Dennis Ritchie's C book is now seriously outdated - the second edition (the most recent) was published in 1988. There have since been several major new specifications of the language (C89, C90, C99, C11) which renders the book obsolete except as a historical document. – Dai May 28 '17 at 10:30
  • 1
    @OliverCharlesworth But in the declaration ` int a[] = {1,2,3};`, we are declaring type, we are not declaring size only. – hanugm May 28 '17 at 10:33
  • 1
    How about enum? – Marichyasana May 28 '17 at 10:42
  • 1
    @hanugm - The size is part of the type. – Oliver Charlesworth May 28 '17 at 10:45
  • @Marichyasana Yeah, I hope its true, An enumeration, in general assigns 0,1 ans so on to variables inside the enumeration without explicitly saying them as integers and also we can assign characters without specifying them as `char`. – hanugm May 28 '17 at 10:49
  • incomplete struct types can also be used without prior declaration – M.M May 28 '17 at 10:57

2 Answers2

11

By "certain declarations" the author means declaration of things which are not variables. At the time the book has been written C allowed implicit declaration of functions: the compiler simply assumed that the function returns integer. Modern C standards make such declarations illegal.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
4

When the first edition of K&R was written, there was no C standard. When the second edition of K&R was written, the C89/C90 standard was about to be finalized. Because of the legacy from code written before C89 was finalized, the standard had to permit:

#include <stdio.h>

double sqrt();

main(argc, argv)
    char **argv;
{
    if (argc > 1)
        printf("sqrt(%s) = %f\n", argv[1], sqrt((double)atoi(argv[1])));
    else
        printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2.0));
    return 0;
}

Note that the return type of main() is implicitly int; the function argument argc is implicitly int; the function atoi() has an implicit return type of int. Note too that the argument to sqrt() had to be explicitly a double value; the compiler could not automatically convert the argument type because prototypes were not a part of C before the C89 standard.

Such code is no longer acceptable to C99 or C11 compilers. You could use:

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

int main(int argc, char **argv)
{
    if (argc > 1)
        printf("sqrt(%s) = %f\n", argv[1], sqrt(atoi(argv[1])));
    else
        printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2));
    return 0;
}

This uses the standard headers to declare the functions with complete prototypes, so it is no longer necessary to cast the argument to sqrt(). In C99 or C11, you could omit the return 0; and the effect would be the same. Personally, I don't like the loophole that allows that and continue to write the return explicitly. The return was necessary in C90 to send a determinate status to the environment (e.g. the shell the invoked the program).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278