Hi all,

I have a C project consisting of five files as follows:

main.c
file1.c
file1.h
file2.c
file2.h

I have defined an array in file file1.h as follows:

static struct prnc keys[MAXP];

the array was populated in file file1.c

Now I need to use the contents of this array again in file file2.c , I don't get a compilation error when i try to print the cotents of the array in file2.c, but at run time I get nothing as if the code is never encountered. So I tried the following two approaches:

1- I changed the definition of the array in file1.h to:

extern struct prnc keys[MAXP];

This time I got a compilation error generated by references to the array in file file1.c, the error message stated that the array is unknown. Why?
so I tried this:

2- I kept the definition in file1.h as:

static struct prnc keys[MAXP];

and added the following line in file2.c:

extern struct prnc keys[MAXP];

the project compiles but at run time the array seems to be empty.

My question is:

The array is populated in file1.c, and I want to reference its contents in

file2.c

, how can I do that? cause I really don't think that answer is to repopulate it in file2.c! or is it?!


Thanks in advance for your help.

Dani AI

Generated

Short answer: put a single definition (storage) in one .c file and put an extern declaration in the header that every .c includes. was right to recommend extern; , your earlier symptoms come from two different linkage issues (internal linkage when you used static in a header, and a missing definition when you used extern but didn’t provide the storage).

Why you saw those behaviors

  • A static at file scope in a header gives each translation unit its own private copy. Filling one copy in file1.c does nothing to the separate copy in file2.c.
  • An extern in the header is only a declaration; it requires exactly one definition (the actual array without extern) in a single .c file. If that defining .c isn’t compiled/linked, you get an undefined-reference (linker) error.
  • Placing a plain uninitialized definition in a header and including it in multiple .c files can sometimes “work” because some toolchains coalesce uninitialized symbols, but that is non‑portable and fragile (and will fail under C++ or stricter linkers).

Practical pattern (rename to avoid copy/paste confusion)

/* shared.h */
#ifndef SHARED_H
#define SHARED_H
#define NUM_KEYS 128
struct prnc;           /* forward if needed */
extern struct prnc global_prncs[NUM_KEYS];
void init_prncs(void);
#endif
/* file1.c */
#include "shared.h"
struct prnc global_prncs[NUM_KEYS];   /* single definition */
void init_prncs(void) { /* populate global_prncs here */ }
/* file2.c */
#include "shared.h"
/* use global_prncs (after init_prncs() has been called) */

Tips and good practice

  • Make sure file1.c is part of the build/link step (gcc main.c file1.c file2.c -o prog).
  • Prefer accessor functions (e.g., const struct prnc *get_prncs(void)) instead of exposing globals.
  • If mixing C and C++ compile units, watch name mangling (use extern "C" for C linkage).
  • Use include guards in headers to avoid double inclusion.

Recommended Answers

All 6 Replies

Lose the static qualifier. extern should be placed on the array in the header file to ensure that it's a declaration. Then include file1.h in both file1.c and file2.c. Make sure that the code to fill the array is called first if you define it in file1.c.

That's exactly what I did the first time and which resulted in the compilation error:
"undefined reference to 'keys' "
where keys is the name of the array.
I'm using bloodshed Dev C++ compiler if it makes any difference.
Suggestions?

Ok check this out,

I defined the array in file1.h as:

struct prnc keys[MAXP];

then, I included the following in file2.c:

extern struct prnc keys[MAXP];

and it worked!
Please let me know if you think this is a poor scheme or that I should go about this in another way.
But either way I really appreciate your help, Thank you : )

>Please let me know if you think this is a poor scheme
I think it's a poor scheme, but since it works for you and you can't seem to figure out how to set up your file dependencies properly, go ahead and use it.

But I want to know the proper way if you can kindly tell me,

file1.c has the following header files:

#include "file1.h"

file2.c has the following header files:

#include "file1.h"
#include "file2.h"

But applying the scheme you're suggesting -which is approach #1 in my first post- does not work.

>But I want to know the proper way if you can kindly tell me
I did kindly tell you. Use extern declarations in your header files, provide a single source file for definitions, and the linker will do the rest. You only need a declaration for the code to compile.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.