Can pointers be accessed globally in C? - c

Can I access pointers from any function without sending info from main() to each function? I've tried looking for information but couldn't find an answer.

Did you try it?
Yes, you can, but using lots of global variables is not a good idea.

If the pointer is passed to the function as parameter or it is declared as global then yes.

Yes you can, because address of variable - it's her own unique identifier in memory space, like a house address within the big city. And e.g. for debug reasons it can be very helpfull (the only thing you should be sure about - live scope of this variable, because when variable leaves her scope - pointer to this address is no longer valid).

As others have said: There are good reasons to not use many globals ("locality of code" is useful), but careful use of globals is justified in some cases. An example might help:
// A slightly contrived example to show how and when you
// might use a global variable in a C program.
#include <stdio.h>
#include <stdlib.h>
// The following are compile-time constants, and considered
// good coding practice
#define DEBUG_WARN 1
#define DEBUG_ERROR 2
// The following is a global, accessible from any function,
// and should be used cautiously. Note the convention (not
// universally adopted) of prefixing its name with "g_"
int g_debug_threshold = 0;
// debug_print() uses the global variable to
// decide whether or not to print a debug message.
void debug_print(char *msg, int level) {
if (level >= g_debug_threshold) {
fprintf(stderr, "%s\n", msg);
}
}
void foo() {
debug_print("hi mom", DEBUG_WARN);
}
int main(int ac, char **av) {
// Here we set the debug threshold at runtime
if (ac > 1) {
g_debug_threshold = atoi(av[1]);
}
foo();
}

Related

Cannot use `getpagesize()` call to set a global variable in C

With the following code
#include <unistd.h>
int a = getpagesize();
int main() {
return a;
}
I receive the following compilation error
3:1: error: initializer element is not constant
What is an "initializer element", and why does it need to be constant? Does that relate to the const qualifier?
The value used to initialize global variables needs to be determined at compile time. The return value of a function (in C, at least) won't be evaluated until run time. So something like:
int a = 4;
is OK, but:
int a = somefunction();
is not. In C++ you can have constexpr functions, but in C you can't.
If you must do something like this, you can always use:
int a;
int main(void) {
a = getpagesize();
/* Rest of your program */
}
Obviously you can't make your global const doing this (since you can only set the value of a const variable at initialization, and you can't initialize globals with functions). Frankly, there's probably no reason why you can't just call getpagesize() when you need it and forget about a global variable altogether - unless you call it a billion times, you won't notice the overhead. If you must have a global variable, then just don't make it const.
If immutability is an absolute requirement, and the problem is avoiding an expensive function call rather than avoiding function calls altogether, then one option is to replace it with an inexpensive function call, like so:
int poor_mans_global(void) {
static int a = -1;
if ( a == -1 ) {
a = getpagesize(); /* Only call the expensive function once */
}
return a;
}
and call poor_mans_global() instead of using your global variable. Note that this example is illustrative only, and doesn't imply that getpagesize() is an expensive function call.
A final option is to package all your code that needs access to this global into a separate translation unit, and make the global static, i.e. file scope rather than truly global. The benefits of const - which are never all that great to begin with, in C - decrease dramatically when you can exert tight control over which code gets to access that variable.

How to give some variables "constant status" that are read from a fixed memory area in the beginning of a embedded program?

Detail of the problem:
Some variables are read from a fixed memory area in RAM into an array. From that array I need to read some variables and use it across the code but these variables need to be constant as they wont be changed in the program any where. Need suggestions to do it effectively! Thanks in advance for any help.
The thought was given for using const variables but then Const variables needs to be initialised during declaration itself. I need to extract bit by bit for each of these variables as I am not able to use memcpy for ensuring portability. Hence I find trouble in declaring the variables as constant.
Put those variables {myVar1, myVar2,...myVarN} into a C file myconsts.c (static to the compilation unit, this will make sure they are not visible outside). Add a header file myconsts.h with function declarations
int getmyVar1(void);
and so on for all the variables and implement the functions in myconsts.c.
They aren't const in the C sense, but they are unwriteable from outside the myconsts.c file. You can initialise them inside myconsts.c, just dont forget to call the init().
If you mean that you are trying to guarantee that these 'constants' end up in flash as opposed to your RAM memory...consult your manual.
You could use inline functions to access the data direct from the array, e.g
static inline myvar() { return array[myvaroffset]; }
Or, if you want the offsets hidden, don't use inline functions and just have a small module that just provides the functions.
If 'myvaroffset' is calculated rather than being a constant and you want to avoid the indexing overhead, copy the array element to a variable during initialisation and return that from the function. If you use real functions, the variables can be static within the function module.
in the function module
/* initialisation */
static int myvarlocal = array[myvaroffset];
...
/* function definitions */
...
int myvar() { return myvarlocal; }
When you want to use it:
i = myvar();
There is probably no need to make things complicated with const pointers etc. Simply use private encapsulation:
// data.h
int data_get (int index);
// data.c
#include "data.h"
static int the_array [N];
int data_get (int index)
{
if(index >= N)
{
// handle errors
}
return array[index];
}

Removing (or rather conditionally attach) const modifier using macros in C

I am dealing with the following issue in C. I use global variables for defining some global parameters in my code. I would like such global variables to be constant, even though they have to be initialized inside a routine that reads their values from an input data file. In a nutshell, I am looking for a good way to "cast away" constness during variable initialization in C (I guess in C++ this would not be an issue thanks to const_cast)
I came up with a pattern based on macros to do so, as illustrated below.
It seems to work fine, but I have the following questions.
Does anyone see any hidden flaw or potential danger in the procedure below?
Would anyone discourage the following approach in favor of a simpler one?
My approach:
I have a main header file containing the definition of my global variable (int N) like so
/* main_header.h */
#ifdef global_params_reader
#define __TYPE__QUAL__
#else
#define __TYPE__QUAL__ const
#endif
__TYPE__QUAL__ int N;
I have a file "get_global_params.c" implementing the initialization of N, which sees N as "int N" (as it includes "main_header.h" after defining global_params_reader)
/* get_global_params.c */
#define global_params_reader
#include get_global_params.h
void get_global_params(char* filename){
N = ... ; // calling some function that reads the value of N from
// the datafile "filename" and returns it
}
and the corresponding header file "get_global_params.h"
/* get_global_params.h */
#include "main_header.h"
void get_global_params(char* filename);
Finally, I have a main.c, which sees N as "const int N" (as it includes "main_header.h" without defining global_params_reader):
/* main.c */
#include "main_header.h"
#include "get_global_params.h"
int main(int argc, char **argv){
// setting up input data file //
...
// initialize N //
get_global_params(datafile);
// do things with N //
...
}
I hope my explanation was clear enough.
Thanks for any feedback.
Just contain the globals in a separate file.
globl.h:
struct Globals{
int N;
//...
};
extern const struct Globals *const globals;
init_globl.h:
init_globals(/*Init Params*/);
globl.c
#include globl.h
#include init_globl.h
static struct Globals _globals;
const struct Globals *const globals = &_globals;
init_globals(/*Init Params*/){
// Initialize _globals;
//...
}
Now you can initialize the globals at startup by including init_globl.h in whatever file needs access to that functionality, everyone else can directly access the globals just by including globl.h, and using the notation globals->N.
If I were you, I would simply avoid this kind of global variables. Instead, I would define a struct with all those program parameters, and define one function that returns a const pointer to the one and only instance of this struct (singleton pattern). That way, the function that returns the pointer has non-const access to the singleton, while the entire rest of the program does not. This is precisely what you need, it's clean and object oriented, so there is no reason to mess around with macros and casts.
The instance can be declared as a static variable within the function or it can be malloc'ed to a static pointer. It does not really matter, because that is an implementation detail of that function which is never leaked to the outside. Nor does the rest of the code need to be aware of when the parameters are actually read, it just calls the function and it gets the one and only object with all valid parameters.
"I would like such global variables to be constant, even though they have to be initialized inside a routine that reads their values from an input data file."
It is not possible to initialize a const in c during run-time. In c value either has or has not a const qualifier, and it is defined upon declaration. c does not support changing it. The semantics are fixed. But some expert with quoting the standard would be nicer and more ensuring.
I don't think this is possible in c++ either, but I won't bet on it, since c++ can do some magic here and there.

Declaration of a variable FILE * (static or not)

My situation is this:
a header aux_func.h with prototype of a function int check_format_file(FILE * file);
a source file aux_func.c with implementation of that funcion
The question is: In my main.c, where and how is better to declare FILE * f ?
As a static global variable
#include aux_func.h
static FILE * f;
int main()
{
check_format_file(f);
/* other stuffs */
return 0;
}
As an istance variable declare in main ?
#include aux_func.h
int main()
{
FILE * f;
check_format_file(f);
/* other stuffs */
return 0;
}
My doubt is about the correct visibility of FILE *f.
In both the cases, you are passing f to the one and only function check_format_file(), so there is no need to make it static and global. Nobody is going to alter the value of f (I hope so, because if somebody is going to modify it, then you have many more worries than this) and the way you are passing it to the other function, makes sure that it will be visible to the function.
From SO Question,
Variables should always have the smaller scope possible. The argument
behind that is that every time you increase the scope you have more
code that potentially modifies the variable, thus more complexity is
induced in the solution.
It is thus clear that avoiding using global variables is preferred if
the design and implementation naturally allows that. Due to this I
prefer not using global variables unless they are really needed.
I would go with the second option because it seems that you are not going to use the variable f out of this function that's why there is no reason to make it global.

warning: declaration of 'index' shadows a global declaration

My Compiler(gcc) is showing the warning
warning: declaration of 'index' shadows a global declaration
Please help me understand why this warning comes.
It's when you do something like:
int index;
int main (void) {
int index;
....
return 0;
}
What it's warning about is that the index inside main() is actually hiding the global one you've declared before main().
It's warning you that you can't get at the global definition while the local one is "active". Now that's not necessarily a problem (hence why it's only a warning), it's perfectly valid C, but you need to be aware of the possible consequences.
As an aside, some C implementations (BSD-based) define an index function in string.h which may also cause a problem. Use of this function is deprecated and it doesn't appear in the C standard (use strchr instead) but it may be the cause of problems if you're running on (for example) Mac OS or OpenBSD (or even Linux under some combination of #define settings, I believe).
There are a couple of ways to get around this (if you need to).
The first is probably the preferred one: don't use globals. Yes, that's right, get rid of them. They're very rarely needed so don't make me come over and slap you around :-)
A second way I've seen is to ensure they're "packaged". Assuming that you actually need globals (by no means a certainty, see previous paragraph), create a structure that holds them, such as in the following:
myglobs.h:
struct sMyGlobs {
int index;
// all other globals.
};
extern struct sMyGlobs myGlobs;
myglobs.c:
#include "myglobs.h"
struct sMyGlobs myGlobs;
main.c:
#include <stdio.h>
#include "myglobs.h"
int main (void) {
myGlobs.index = 42;
return 0;
}
This has the advantage in that it's obvious that you're referring to a global and that they're never hidden, unless you do something like define your own local variable called myGlobs.

Resources