1

I have started programming in C and in general I'm looking for "best practices" to structure my code.

Having mainly used object oriented languages before, I started to adopt some practices from these languages.

My concrete question is: Is this code considered "acceptable" C code or am I running into a common trap for people trying to use encapsulation in C?

// A.h 
void setValue(int);
int getValue();

// A.c 
#include "A.h"

int my_private_value;

void setValue(int v)
{   
  my_private_value = v;
}   

int getValue(void)
{   
  return my_private_value;
}
Jens
  • 69,818
  • 15
  • 125
  • 179

5 Answers5

7

To be pedantic: there are no global variables in C. Variables have scope, storage duration and linkage. For none of these there exists a 'global' qualification.

So what is going on, then? Your

int my_private_value;

is a variable with with file scope and external linkage (and static storage duration). This type of linkage means it can be referenced from any other file that has an extern int my_private_value declaration in scope. To avoid this, the variable must have internal linkage. To declare a variable with internal linkage, use the static keyword:

static int my_private_value;

So, if you wanna sound like a professional, whenever you are tempted to utter 'global variable', take a deep breath and speak the words object with file scope and external linkage. That'll make you shine in all C interviews :-)

Should somebody question your wisdom about the lack of "global" variables, you can even prove it to them. Global variables are in scope everywhere, right? But in C, the scope of an object starts not until its declaration. The lack of a truly global variable makes it impossible to forward reference a variable like in

 int *foo = &bar;   /* Doesn't work in C: bar is not (yet) in scope. */
 int bar = 42;

It does work when you swap the two lines.

Jens
  • 69,818
  • 15
  • 125
  • 179
4

The only change I would make to your code is how my_private_value gets defined. I would define it as:

static int my_private_value;

This prevents external code modules from declaring extern int my_private_value; and then accessing it directly.

mah
  • 39,056
  • 9
  • 76
  • 93
2

This is OK, but you need to make the variable static so that it has internal linkage; the way it is now, code in other files will be able to directly access it. See this for more information on linkage and how it affects the accessibility of variables, or this question that deals with the same matter.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
1

For the access and availability of the variable, others have already answered, but generally I'd say that you'd have to have good reasons for such a kind of interface. It does reduce the potential of the compiler to optimize the access to the object.

What is not acceptable in C is this declaration:

int getValue();

which in C isn't a prototype. It declares a function that may receive an unspecified number of arguments. Instead, use:

int getValue(void);
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

I've seen this being done in C before and there's nothing wrong with it until you 1. don't want to be thread-safe (which you do want, in fact) and make the global variable static and not expose it through a header file. That said, using global vaiables is bad practice and should be avoided if possible.

  • 1
    translation: 'there's nothing wrong with this, except for all these things i'm about to list, which are very wrong.' ...ok then. – underscore_d Aug 26 '16 at 11:34