-1

This works when I declare my variable locally but, when I try to declare this variable in a header file, it gives me this error. Does anyone know what I'm doing wrong?

In file included from myshell.c:2:
myshell.h:19:5: error: redefinition of ‘output_file_found’
   19 | int output_file_found = 0;
      |     ^~~~~~~~~~~~~~~~~
In file included from commands.c:1,
                 from myshell.c:1:
myshell.h:19:5: note: previous definition of ‘output_file_found’ was here
   19 | int output_file_found = 0;
      |     ^~~~~~~~~~~~~~~~~
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    _Declare_ it `extern int output_file_found;` in `myshell.h` and _define_ it `int output_file_found = 0` in `myshell.c` (and **only** in `myshell.c`) – Ted Lyngmo Mar 10 '22 at 17:59
  • Also, don't include one .c file in another .c file. – dbush Mar 10 '22 at 18:07
  • 1
    There are *hundreds* of related duplicates of this problem. [this is one of them](https://stackoverflow.com/questions/2206853/struct-with-a-value-in-a-header-file-causing-duplicate-symbol-linker-error). The short version: headers are for declarations; not definitions. – WhozCraig Mar 10 '22 at 18:08
  • Note [What is the difference between a definition and a declaration?](https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration) Amongst other things, recognize that all definitions are also declarations, but not all declarations are definitions. – Jonathan Leffler Mar 11 '22 at 16:20

1 Answers1

1

int output_file_found = 0; defines output_file_found.1 Because myshell.h is included twice, output_file_found is defined twice, but there should be only one definition of a variable in the entire program. (By nesting blocks inside other blocks, the same name can be used for different variables, so there can be multiple definitions of different variables with the same name. However, both of these declarations appear at file scope, so they attempt to define the same variable.)

In myshell.h, change the code to extern int output_file_found;, so that it is only a declaration that is not a definition. In one .c file in your program, put int output_file_found = 0;, so there is only one definition.

Do nto include myshell.c from commands.c. Source files should only include header files. (The compiler does not much care about the file name suffix, but convention is to use .c for C source files and .h for header files.) To use multiple source files in your project, compile them separately into object files, then link the object files together into one program.

It is also common to use “header guards” to prevent the declarations in a header from being processed multiple times by the compiler, in case one header is included multiple times through different paths of nested inclusion by other headers. This will not matter for a variable declaration done correctly, such as extern int output_file_found;, but it can matter for type definitions and some other declarations. To do this, include these lines at the beginning of the header file:

#if !defined ThisHeaderName_h // Test whether guard has been defined.
#define ThisHeaderName_h      // Define guard.

and this line at the end of the header file:

#endif // Matching #if !defined ThisHeaderName_h.

Footnote

1 A declaration with an initialization is a definition. Some other declarations may be definitions too, but the rules are complicated.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312