6

i have 2 source files (.c) named file1.c and file2.c which need to share between them a variable, so that if in one source file the variable is been updated then in the other sourced file when accessing this variable the change will be seen.

what i did is create another source file called file3.c and header file called file3.h (which, of course, is been included in file1.c file2.c and in file3.c)

in file3.c:

int myvariable = 0;

void update(){//updating the variable

    myvariable++;

}

int get(){//getting the variable

    return myvariable;

}

in file3.h:

extern int myvariable;

void update(void);

int get(void);

in file1.c:
.
.
.
printf("myvariable = %d",get());//print 0
update();
printf("myvariable = %d",get());//print 1
.
.
.

in file2.c:
.
.
.
printf("myvariable = %d",get());//print 0 but should print 1
.
.
.

but the problem is when in file1.c update is invoked and myvariable is updated the change cannot be seen in file2.c because in file2.c when get is invoked and myvariable is printed then 0 is been printed, only if in file2.c update is invoked then the change is been seen. it seems like the variable is shared but for each source file there is a different variable value/different memory for this variable

  • How are you compiling these files to create the executable ? – dpp Apr 27 '12 at 18:23
  • in file1.c and file2.c do you also declare "int myvariable;"? You should not. – Heath Hunnicutt Apr 27 '12 at 18:46
  • i compile them with a makefile which i was given by someone and no i don't declare them in any file, only in file3.c and in file3.h as i wrote. –  Apr 27 '12 at 18:51
  • How large is this code? Can you post the entire source here? If it is too large perhaps you can use pastebin etc. It's really hard to debug this problem without all of the code. It sounds like you've implemented what people suggested, so *something* else is probably happening. Have you tried using a debugger to step through the code> – Chimera Apr 27 '12 at 20:35
  • 2
    Given that each file would need less than 30 lines of code, you should post complete, compilable examples of the files (but just have the files contain only what's necessary to show the problem). There's something important missing in posted currently. – Michael Burr Apr 27 '12 at 20:56

4 Answers4

3

You can declare the variable as extern in the others file when you need the variable ...

aleroot
  • 71,077
  • 30
  • 176
  • 213
  • Yes that can be done, but often it's better to not create many global variables. Create the variable to have file scope ( static ) and provide access functions as needed in that file. The rest of the application ( from different files and scope ) will *have* to use the access functions then. Usually leads to a cleaner design and easier to debug and maintain. – Chimera Apr 27 '12 at 19:39
2

include file3.h in file1.c and file2.c

keety
  • 17,231
  • 4
  • 51
  • 56
  • i already did it as i wrote "... called file3.h (which, of course, is been included in file1.c file2.c and in file3.c)" –  Apr 27 '12 at 18:38
  • sorry may seem obvious but does `update` and `get` have `int myvariable` inside the function ? if not could you add the get and update code . – keety Apr 27 '12 at 18:58
  • void update(void){ myvariable++; } int get(void){ return myvariable;} –  Apr 27 '12 at 19:04
  • 1
    also just noticed you got `extern myvariable` in header instead of `extern int myvariable` – keety Apr 27 '12 at 19:06
  • i forgot to write it here but in my code it is written and now i edit my code –  Apr 27 '12 at 19:23
  • @Elizabeth could you add how file2.c function is invoked and also add the code that calls update and get. Also you could add `printf("%p\n",&myvariable);` in update() and in `file1.c` and `file2.c` before you call update if the address is same you are pretty much resetting the variable somewhere else you have another static scope `myvariable` in one of the files . – keety Apr 27 '12 at 19:31
2

I recommend to avoid extern variables because of code clutter - repeating externs in each and every file using that global. It is usually better to bind global variable to some file scope by making it static. And then to use interface functions to access it. In your example terms it will be:

// in file3.h
void update(int x);
int get(void);

// in file3.c:
static int myVariable = 0;

void update(int x){
  myVariable = x;
}

int get(){
  return myVariable;
}

// in other files - include file3.h and use 
// update() / get() to access static variable
Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
  • Nonsense. The `extern` variable declaration properly belongs in the `file3.h`, which would necessarily be included even with your method, which is about access control. Code clutter is not the issue here. – kittemon Apr 27 '12 at 18:34
  • 1
    My method don't exposes `extern` variable - just two functions for reading/writing to it. Sometimes it is good approach too. – Agnius Vasiliauskas Apr 27 '12 at 18:43
  • 0x69 - it doesn't work for me. if i invoke this update(5) in file1.c and then printed there - it will print 5. but after that when i invoke get() from file2.c and print it then 0 is printed and not 5 as i would want. –  Apr 27 '12 at 18:46
  • It can't be so with my solution. – Agnius Vasiliauskas Apr 27 '12 at 18:53
  • Maybe some buffer overflow bug somewhere which overwrites unintentionally your global ? – Agnius Vasiliauskas Apr 27 '12 at 18:54
  • 1
    or maybe you have a lot of places which updates this variable to zero BEFORE you try to get it... It would be good if you would show your full code. There is no magic here. – Agnius Vasiliauskas Apr 27 '12 at 18:56
  • i edit my message and added more details but the code is simple, maybe there is something little which i didn't notice even though i am working at this for several hours and could not find my error. –  Apr 27 '12 at 19:24
  • @0x69 I understand that your code doesn't expose an `extern` variable; also, I agree that your approach is often very useful. My point was that with either approach, other files should only `#include "file3.h"`, so there is no more clutter when using `extern` than with the method you've shown. – kittemon Apr 27 '12 at 19:25
  • i mean clutter in file `file3.h` :-) but yes - clutter is not an issue in this problem ... – Agnius Vasiliauskas Apr 27 '12 at 19:33
2

Here is just one possible solution. Doing this the the variable isn't global to the entire application and can only be read/written to using the access functions. Please let me know if you have questions.

Files: access.c access.h file2.c main.c
Compile with: gcc main.c file2.c access.c -o test
Run: ./test

File: main.c

#include <stdio.h>
#include "access.h"

int main( int argc, char *argv[] )
{
    int value;


    put( 1 );
    printf("%d\n", get());

    put( getValue() + 1 );
    printf("%d\n", getValue());

    return(0);
}

File: access.c

#include "access.h"

static int variable = 0;


int get( void )
{
    return(variable); 
}

void put( int i )
{
    variable = i;
    return;
}

File: file2.c

#include <stdio.h>
#include "access.h"


int getValue( void )
{
    int i = get();

    printf("getValue:: %d\n", i);

    put(++i);
    printf("after getValue:: %d\n", get());
    return( i );
}

File: access.h

extern int getValue( void );
extern int get( void );
extern void put( int i );

And here is the run output:

[root@jrn SO]# ./test
1
getValue:: 1
after getValue:: 2
getValue:: 3
after getValue:: 4
4

I hope this helps.

Chimera
  • 5,884
  • 7
  • 49
  • 81