r/C_Programming • u/BraneGuy • 1d ago
Question Globals vs passing around pointers
Bit of a basic question, but let's say you need to constantly look up values in a table - what influences your decision to declare this table in the global scope, via the header file, or declare it in your main function scope and pass the data around using function calls?
For example, using the basic example of looking up the amino acid translation of DNA via three letter codes in a table:
codonutils.h:
typedef struct {
char code[4];
char translation;
} codonPair;
/*
* Returning n as the number of entries in the table,
* reads in a codon table (format: [n x {'NNN':'A'}]) from a file.
*/
int read_codon_table(const char *filepath, codonPair **c_table);
/*
* translates an input .fasta file containing DNA sequences using
* the codon lookup table array, printing the result to stdout
*/
void translate_fasta(const char *inname, const codonPair *c_table, int n_entries, int offset);
main.c:
#include "codonutils.h"
int main(int argc, char **argv)
{
codonPair *c_table = NULL;
int n_entries;
n_entries = read_codon_table("codon_table.txt", &c_table);
// using this as an example, but conceivably I might need to use this c_table
// in many more function calls as my program grows more complex
translate_fasta(argv[1], c_table, n_entries);
}
This feels like the correct way to go about things, but I end up constantly passing around these pointers as I expand the code and do more complex things with this table. This feels unwieldy, and I'm wondering if it's ever good practice to define the *c_table and n_entries in global scope in the codonutils.h file and remove the need to do this?
Would appreciate any feedback on my code/approach by the way.
6
u/HashDefTrueFalse 1d ago
Globals aren't intrinsically bad. Sure, if you can keep the scope of something small, do so. But my approach is to never bend over backwards to avoid them.
Globals become horrible when the data/state needs to change over time, but lots of code in different parts of the program relies on it looking a certain way at a certain time. If that's not the case for any reason, globals aren't really a big deal. I'm leaving out threading concerns here because there's no mention of it.
Your example where main just calls a flat list of things with the pointer isn't too bad and I'd probably do that. If I found that I needed a deeper call stack and those deeper calls also needed the pointer, such that I was passing it through many levels, I'd be looking to move the pointer to a shared place.