0

Let's say I have a global variable

 char  Dir[80];  /* declared and defined in file1.c  but not exported using extern etc */

The Dir variable is the name of a directory created at run time in the program's main(). In this file we manipulate this variable and pass it to a function func defined in file2.c This Dir variable is a directory in which all functions create thier individual logs.

Instead of passing this variable n number of times to each one of the functions which finally called func().I made it global.

func(x,Dir); /* x is a  local variable in a function  */

/* now in file2.c */

void func(int x,char *Dir)
{
   /*use this variable Dir */
}

The value of Dir we receive here is not the same as in file1.c. Why ? Compiler: gcc on Windows

user1437565
  • 21
  • 1
  • 1
  • 3
  • 2
    It might be different because you are expecting `Dir2` instead of `Dir`? – Mike Kwan Jun 05 '12 at 14:16
  • @MikeKwan that was a copy paste error but I have corrected it – user1437565 Jun 05 '12 at 14:19
  • 1
    Well that code by itself is fine. Can you show a minimal example which reproduces your issue? – Mike Kwan Jun 05 '12 at 14:22
  • The value of `Dir` will be the same if this is how you have written your code. What makes you think it is not? – ArjunShankar Jun 05 '12 at 14:26
  • how you have initialized char Dir[80]? – Aftnix Jun 05 '12 at 14:30
  • Although if you have defined `Dir` globally, it is actually unnecessary to pass it at all. It can be used directly from `file2.c` as long as you declare it an `extern` in the corresponding header file. – Mike Kwan Jun 05 '12 at 14:31
  • @MikeKwan ...which in turn is known as spaghetti, tight coupling and other bad names. The proper advice here would be to declare Dir as `static char Dir[80]` and then pass it as parameter to the function. With that simple keyword, we have removed dependencies, spaghetti and introduced private encapsulation. – Lundin Jun 05 '12 at 14:35
  • ...if the variable even need to be declared at file scope in the first place... – Lundin Jun 05 '12 at 14:39
  • @Lundin: There are sometimes good reasons for using global variables, I'm well aware of the repercussions of doing so. My answer both answers his question and demonstrates the common way for sharing/passing variable values. – Mike Kwan Jun 05 '12 at 14:40
  • @MikeKwan I don't agree, that is a myth. There is no good reason to use (non-constant) global variables ever. The only case I have _ever_ used (non-constant) global variables in my past 10 years as a C programmer, is when declaring hardware registers for embedded microcontroller systems. Please note that a variable declared as static, at file scope, is not a global variable. – Lundin Jun 05 '12 at 14:43
  • @Lundin: The example you give is exactly one of those given by the accepted answer in this question: http://stackoverflow.com/questions/176118/when-is-it-ok-to-use-a-global-variable-in-c I'm not suggesting global variables may be the best solution in this case, but I see no reason to withhold that information in case he requires them at some point in the future. – Mike Kwan Jun 05 '12 at 14:45
  • @user1437565: Please make a minimal code example of what you are trying which exhibits the problem. – Mike Kwan Jun 05 '12 at 18:36

1 Answers1

6

Your code is fine as it stands. I can give you an example of how multiple source files should be used in C and you can compare with what you have written.

Given a main.c and a some_lib.c containing func, you need to define a some_lib.h which defines the function prototype of func defined in some_lib.c.

main.c:

#include <stdlib.h>
#include <stdio.h>
#include "some_lib.h"
/*
 * This means main.c can expect the functions exported in some_lib.h
 * to be exposed by some source it will later be linked against.
 */

int main(void)
{
    char dir[] = "some_string";

    func(100, dir);
    return EXIT_SUCCESS;
}

some_lib.c (contains definition of func):

#include "some_lib.h"

void func(int x, char * dir)
{
    printf("Received %d and %s\n", x, dir);
}

some_lib.h (contains function prototype/declaration of exported functions of some_lib.c):

#ifndef SOME_LIB_H
#define SOME_LIB_H
#include <stdio.h>

void func(int x, char * dir);

#endif

The above should then be compiled with:

gcc main.c some_lib.c -o main

This will produce:

Received 100 and some_string

However, if you are indeed using a global variable, it is not even necessary to pass dir at all. Consider this modified main.c:

#include <stdlib.h>
#include <stdio.h>
#include "some_lib.h"

char dir[] = "some_string";

int main(void)
{
    func(100);
    return EXIT_SUCCESS;
}

dir is defined in here and is globally accessible/defined. All we need to do is make sure that some_lib.c knows that it exists. The linker can then resolve this symbol during the linking stage. some_lib.h needs to be defined as so:

#ifndef SOME_LIB_H
#define SOME_LIB_H
#include <stdio.h>

/*
 * The extern informs the compiler that there is a variable of type char array which
 * is defined somewhere elsewhere but it doesn't know where. The linker will
 * match this with the actual definition in main.c in the linking stage.
 */
extern char dir[];
void func(int x);

#endif

some_lib.c can then use the globally defined variable as if it were scoped:

#include "some_lib.h"

void func(int x)
{
    printf("Received %d and %s\n", x, dir);
}

Compiling and running this will produce the same output as the first example.

Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
  • It should be noted that example 1 with dir as a local is good programming practice, and example 2 with dir as a global is very bad programming practice. – Lundin Jun 05 '12 at 14:40
  • For more information on global variables, see here: http://stackoverflow.com/questions/176118/when-is-it-ok-to-use-a-global-variable-in-c. – Mike Kwan Jun 05 '12 at 14:42
  • I have programmed C for ages, everything from real time embedded systems to PC graphic fluff. I have _never_ had the need to use a global variable. In my experience, the need of global variables comes from: 1) muddy thinking, and/or 2) poor program design, and/or 3) poor knowledge of the C language: failing to understand mechanisms such as static variables, inlining and opaque data types (pointer to an incomplete type that is privately encapsulated). – Lundin Jun 05 '12 at 14:48
  • I did want to pass it an extern as that second file is given by client and cannot be changed. – user1437565 Jun 05 '12 at 18:33