0

I've been writing C for years now, but I've never learned how to structure things. I've just made giant programs in one file and used global scope for variables that are modified by multiple functions. I'm trying to break away from this and group my functions in separate files. The biggest problem I've had is with variable scope.

For example, one variable needs to be written to by two separate functions in different files and read by two more. I could declare it in main.c and make it an extern in the others, but I know globals are frowned upon and it seems sloppy.

So, is there a logical, "correct" place to declare it? Should it have something like get/set functions? Or is this problem indicative of me poorly dividing my functions?

Thanks.

Skidlz
  • 1
  • 1
  • Good way would be to keep your variables in .h file.(with extern) and include the .h file in whichever .c files you need. – Gopi Oct 09 '14 at 10:46
  • the proper place to put them is main() not outside main(), then passing them to the functions that need them – AndersK Oct 09 '14 at 11:18
  • In my prog, putting vars in main forces me to pass ~10 values down through 4 functions. I'd also have to return modifications up through that. – Skidlz Oct 09 '14 at 11:28

2 Answers2

1

Stop thinking in terms of variables and start thinking of values. Pass values to functions that need them, only pass them what they need, and gather related values in structs to reduce the number of arguments when needed. Let functions return their result instead of writing it into a global. This is the way to organize programs in any language, including C. (See Pike's Notes, especially rule 5: "data dominates".)

Using getters and setters on global variables can buy you some safety, but it doesn't solve the real problems with global state. You still need to figure out which parts of the program are using which data and make sure they're touching the data in the right order.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Passing values is great, but changing variables is a problem. I guess I could pass pointers. – Skidlz Oct 09 '14 at 11:17
  • @Skidlz Why is it a problem? I've worked on largish software systems in C that didn't use a single global variable. – Fred Foo Oct 09 '14 at 11:27
  • I can keep my vars in main() and pass their values along, but that only works in one direction. I'd have to use returns to do all my modifications. Right? – Skidlz Oct 09 '14 at 11:35
  • @Skidlz: yes. Sorry, I misunderstood. You can also return structs, but if you must modify unrelated data and/or signal errors, then passing by pointer is often the best option. – Fred Foo Oct 09 '14 at 11:48
1

Allocate the variable dynamically using malloc and pass the pointer to the variable to the functions (or pass by reference if you are using C++). You can define the variable as extern in a header file and include that file wherever needed, as mentioned by @pala.

For the functions which will only read the value pointed by the pointer, you can define it as 'pointer to constant'. This will avoid accidental updation of the content by that function. If you are sure that the address of the memory location also will remain constant in the function you can define 'constant pointer to a constant'. Check this page for on const pointer and pointer to constant.

Returning updated value of a function is also OK, but if there are many functions updating the variable it would be difficult to manage.

If you have multiple threads updating a common variable, make sure you use mutex or semaphore to avoid synchronization issues.

Abhishek
  • 19
  • 3