1

On file1 I've defined the variable args as:

CLA args;

On file2 I've declared it as:

extern CLA* args;

The program would compile with both gcc and clang with no errors, and no errors would appear on valgrind either. There was a problem though: On file2 the function fprintf(args->output, ...) would not print anything. Why there were no errors issued?

Nick
  • 260
  • 3
  • 11
  • Try to imagine a sensible compiler error to issue in this case. I don't think you can do it. I have a file3 on my machine that declares `args` as an `int`. Should your compiler warn about that? – David Schwartz Jul 15 '16 at 22:22
  • 2
    This is why you need a header to declare the variable (if you really must use a global variable), and the header is then included by both source files, and acts as the referee — it will cause the compiler to reject the erroneous file. See [How do I use `extern` to share variables between source files in C?](http://stackoverflow.com/questions/1433204/). – Jonathan Leffler Jul 15 '16 at 22:28

2 Answers2

5

The program would compile with both gcc and clang with no errors

Because each C file is compiled independently. When the resultant object files are linked, the linker has only symbol names. It does not know the types associated with those symbols.

This is one of the reasons1 that C++ uses name mangling: the type of the symbol is embedded in its name, so if there is a mismatch, link failure will occur.

This is why you either don't use globals, or you declare them in header files, and include that header file everywhere you reference said global, including the unit that defines it.

There is never a reason for extern to show up in a .c file; only in a .h file.

and no errors would appear on valgrind either.

We haven't seen your source code so we can't know how you might be using said variable incorrectly in such a way that valgrind would detect it.


1 - The other, primary reason is to support overloaded functions.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • Do C++ global variables get name mangled? GCC (`g++`) 7.2.0 on a Mac compiles `int gobbledygook = 13;` to an object file defining `0000000000000000 D _gobbledygook` according to `nm`. – Jonathan Leffler Sep 14 '17 at 04:45
2

Do the following instead:

Create a header file, let's call it globals.h. It should look similar to this:

#ifndef GLOBALS_H
#define GLOBALS_H

/* include whatever you need, declare the CLA type */

extern CLA *args;

/* define/declare/etc. whatever you need here. */

#endif

In the first file, do:

#include "globals.h"

In the second file, do:

#include "globals.h"

/* rest of code here */

CLA *args = NULL;

/* more code here */
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94