20

How to create an external character array in C?

I have tried various ways to define char cmdval[128] but it always says undefined reference to 'cmdval'

I want to put a string in cmdval in first.c file and use it in other second.c file. I tried adding a global.h file with extern char cmdval[128] but no luck.

UPDATE:

global.h

extern char cmdval[128];

first.c

#include "global.h"

char cmdval[128];

function(){
   strcpy(cmdval, "a string");
}

second.c

#include "global.h"

function(){
   printf("%s \n",cmdval); //error
}

FAIL :( "undefined reference to `cmdval'"

EDIT: I am working in linux (editing a mini OS xv6 then compiling and running it in qemu), I don't know if it is a barrier

SMUsamaShah
  • 7,677
  • 22
  • 88
  • 131

4 Answers4

42

You need to declare it in the .h file

extern char cmdval[128];

And then define the value in first.c;

char cmdval[128];

Then anything that includes your .h file, provided it is linked with first.o will have access to it.

To elaborate, "extern" is saying, there is an external variable that this will reference... if you dont then declare cmdval somewhere, cmdval will never exist, and the extern reference will never reference anything.

Example:

global.h:

extern char cmdval[128];

first.c:

#include "global.h"
char cmdval[128];

int main() {
  strcpy(cmdval, "testing");
  test();
}

second.c:

#include "global.h"

void test() {
  printf("%s\n", cmdval);
}

You can compile this using:

gcc first.c second.c -o main

Or make the .o files first and link them

gcc -c first.c -o first.o
gcc -c second.c -o second.o
gcc first.o second.o -o main
Geoffrey
  • 10,843
  • 3
  • 33
  • 46
  • 'provided it is linked with first.o' what does that mean? – SMUsamaShah Oct 06 '11 at 06:21
  • Also do i need to define char cmdval in second.c? – SMUsamaShah Oct 06 '11 at 06:21
  • They are part of the same binary, eg: `gcc first.c second.c -o main`, and no, you only declare cmdval once, but you still need the extern in global.h – Geoffrey Oct 06 '11 at 06:22
  • 2
    Take the `128` out of the extern declaration. `extern char cmdval[]` is enough. If you leave a value in the declaration and the definition is changed, the declaration's value will be ignored. – Eran Oct 06 '11 at 06:24
  • I am working in linux (editing a mini OS xv6 then compiling and running it in qemu), I don't know if it is a barrier – SMUsamaShah Oct 06 '11 at 06:30
  • I just compiled my example using `gcc first.c second.c -o main` and then ran it as `./main` which produced `testing` – Geoffrey Oct 06 '11 at 06:31
  • are these two .c files part of the same project/binary? – Geoffrey Oct 06 '11 at 06:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4057/discussion-between-geoffrey-and-lifeh2o) – Geoffrey Oct 06 '11 at 06:37
  • Using the 128 in the `.h` file declaration is usually the *right* thing to do; if it conflicts the definition in the `.c` file then you will get a compile-time error (provided you include the `.h` file in the `.c` file, which is exactly why you should do that). Including the size in the declaration means that it will have a complete type in all translation units. – caf Oct 06 '11 at 09:04
  • @caf - good good point, didnt even think of that, thanks, re-updating the example. – Geoffrey Oct 06 '11 at 09:11
  • Why do I get an error when I use `extern char* cmdval;` instead (in the `.h` file)? – Elliot Gorokhovsky Nov 17 '18 at 06:40
  • @ElliotGorokhovsky you have not provided enough information. Please ask your question as a new question with details, this is not the place to ask about a separate issue. – Geoffrey Nov 17 '18 at 20:14
  • No worries, I figured it out. It was a simple error with my include guards. – Elliot Gorokhovsky Nov 17 '18 at 20:40
4

Extern doesn't mean find it somewhere, it changes the variable linkage to external, which means no matter how many time you declare a variable, it references to the same thing.

e.g. These references the same thing in c(not c++), a global variable's linkage by default is external.

external char cmdval[128];
char cmdval[];
char cmdval[128];

The problem is that you shoud first compile them into .o, then link those .o together.

gcc -c first.c second.c
gcc -o first.o second.o

or

gcc first.c second.c
lostyzd
  • 4,515
  • 3
  • 19
  • 33
2

You should have a compilation unit in which you define the cmdval variable. The extern keyword only declares that the variable exists, it does not define it.

Put the following line in first.c, second.c or in an other C file of your choice:

char cmdval[128];
0

In second.c

#include "global.h"

define extern char cmdval[128] in global.h as well.

Pete Houston
  • 14,931
  • 6
  • 47
  • 60