include library in C is required?

1

I came across the following situation:

  

Ubuntu 16.01

     

gcc --version

     

gcc (GCC) 6.3.0   Copyright (C) 2016 Free Software Foundation, Inc.   This is free software; see the source for copying conditions. There is NO   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

test.c

main() {
    printf("Hello Word.\n");
    printf("pow function : %f \n", pow(10,2));
}

Use this command to compile:

gcc -std=c11  test.c -o test

test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main() {
 ^~~~
test.c: In function ‘main’:
test.c:4:3: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
   printf("Hello Word.\n");
   ^~~~~~
test.c:4:3: warning: incompatible implicit declaration of built-in function ‘printf’
test.c:4:3: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
test.c:5:35: warning: implicit declaration of function ‘pow’ [-Wimplicit-function-declaration]
   printf("powf function : %d \n", pow(10,2));
                                   ^~~
test.c:5:35: warning: incompatible implicit declaration of built-in function ‘pow’
test.c:5:35: note: include ‘<math.h>’ or provide a declaration of ‘pow’

And I ran the generated file:

./test

Hello Word.
pow function : 100.000000

I ask: Am I required to do #include <stdio.h> and #include <math.h> ? this applies to all standard library ?

File changed:

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

int main() {
    printf("Hello Word.\n");
    printf("powf function : %f \n", pow(10,2));
    return 0;
 }

Command to compile (in this case you do not have warnings):

gcc -std=c11  test.c -o test

Output:

./test

Hello Word.
pow function : 100.000000

In both cases the output is the same.

    
asked by anonymous 22.04.2017 / 15:41

3 answers

6

If you use something from this library then you have to use yes.

Depending on the compiler and its settings you may find the functions to link .

When you generate warning it means your code is wrong, but it can generate an executable. If it will work is a matter of coincidence. It may or may not work depending on the operation and the desired result.

Every professional programmer treats warnings as if they were errors because they are errors. Just do not prevent compilation.

One thing I always say and few listen is that being right and working are very different things. The right is what you want. What works is circumstantial or coincident. It works, but nothing guarantees that it will continue like this in all situations. One mistake that beginner programmers commit, and some are beginners even after decades of doing it, is to test to see that it gave what it wanted to see and to think that it is right. It is only right that it can be proved that what is desired in all possible situations, including those unlikely to happen, is happening.

Of course proving that everything is right all the time is almost unfeasible. So software has bugs . You prove to some extent. The problem is that if you prove only in one situation the chance of the code having a bug might be more than 50%. If you try the easy things and you leave only what is difficult without proofs, or something that you did not think and it is rare, then the chance of a bug gets less than 1%.

Then it is mandatory to set include , even if this does not prevent compilation in a specific situation.

Note that a compiler ideally configured would give error and would not compile.

If you want to know more about include you already have a question about it: How does the Include directive work? . Also: Using function and header file .

    
22.04.2017 / 16:18
4

What is the #include ?

#include is a preprocessor directive, that is, a transformation of program text that occurs before the parsing itself. It receives a file name as a parameter and replaces itself with the text of the file mentioned: thus, a line like this:

#include <stdio.h>

It will be replaced by the contents of the stdio.h file in a specific directory on your machine (in the case of Ubuntu, it is probably /usr/local/include/ , but may be different).

Of course, there are many ways to take advantage of this mechanism, but the standard way to use it is to include so-called header files where its default extension .h ). These are C language files, but they contain only:

  • Definitions of preprocessor macros (via #define and other related mechanisms, for example, setting NULL to stddef.h );

  • Type definitions (for example, type FILE * defined in stdio.h or struct tm in time.h );

  • Declarations of global variables such as errno in errno.h ;

  • Declarations of functions, where the file tells the compiler that a function with a given name exists, and what parameters it receives and what type of value they return;

    / li>
  • Include other headers on which headers depend.

And in my case?

In your case, you can see that you used two functions: printf() and pow() . The function declarations are as follows:

int printf(const char * format, ...);
double pow(double base, double exponent);

When the compiler encounters a function invocation that has not been previously declared, it issues a complaining warning and assumes that the function returns int and receives an undetermined number of parameters. In the case of the two functions above, they receive and return primitive types, and therefore the invocation of these functions functions, although type checking is impaired.

Now if instead of printf() you try using fprintf() , which receives as the first parameter stream type FILE * , you would need to pass the correct stream ( stdout so that fprintf() reproduces the effects of printf() ), which is declared in the stdio.h header. When compiling this code, you would get an error of undefined symbol 'stdout' and the compilation would stop.

Type system

Another disadvantage of invoking functions that have not been previously declared is that this disables type checking for the function invocation. You may end up passing a parameter of a wrong type to the function (for example, passing an integer in place of the string formatting to printf() ) and the compiler will not detect the problem. >

At this point you have a program that compiled, but it will have some strange behavior when you execute that function (it can generate a protection error or worse: keep running).

TL; DR

If you invoke functions from the default C library without loading the corresponding headers, the invocation can work if the function in question does not ask for a parameter or return any value, type, or global defined in the header. As programs increase in complexity, the likelihood of this happening tends to zero.

    
23.04.2017 / 03:14
2

In short, the #include macro copies the entire contents of a header file to another header file or source file. Many people confuse the standard C files with the C language itself, and this is a serious error. C is only the language itself, the set of syntactic rules and keywords that make up a program. The standard C library is a work built on the fundamental foundations of language.

So, yes, you need to add #include to all files that use functions, macros, variables, and data structures from another C file.

Extra: Some compilers, such as GCC, can detect when you make use of a standard C library function. In GCC, for example, if you use the printf function, the compiler immediately recognizes the function, includes implicitly the header file stdio and generates a warning. It is not good, nor sustainable, to make use of this function, so always include the necessary header files, even if they are part of the C standard.

    
23.04.2017 / 05:05