Declaration of a variable FILE * (static or not) - c

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.

Related

Is the illustration on Aliasing in C correct?

I saw the link http://www.cs.uregina.ca/Links/class-info/cplusplus/Standards/Disk10/aliasing_c.html about aliasing in c. The program there is shown below.
/********************************
An example of aliasing in C.
Output:
3
3
********************************/
#include < stdio.h >
int main()
{
int G_Var = 2;
/* call SomeFunction with the Global Variable as a parameter */
SomeFunction(G_Var);
return 0;
}
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
{
int G_Var;
int InputVar;
/* Global Variable is set to new value */
G_Var = InputVar + 1;
/* Equivalent to G_Var = G_Var + 1 */
printf("%i\n", InputVar);
printf("%i\n", G_Var);
}
Is the code correct and is working according to what is commented in the code?
Whoever wrote the link was severely incompetent and shouldn't be teaching C. They should rather enlist in a beginner's class themselves.
int G_Var = 2; is not a global variable, it is a local one with automatic storage duration. Both the one in main() and the one inside the function.
The code posted is C++, not C. C does not have references.
The term alias/aliasing refers to when several pointers (or C++ references) may be assumed to point at the same memory location.
int InputVar; in the function conflicts with the parameter name so the code doesn't make any sense. In case there were no name conflict, the variable would be uninitialized and then used, which would be senseless.
Is the code correct and is working according to what is commented in the code?
Whoever wrote this example was so confused that it's really hard to be telling what they are trying to teach, or in which language for that matter. The code does not compile for multiple fundamental reasons. Just forget about this mess.
Four things to say:
C does not have C++-kind of aliases/references. It is a C++ feature only.
So,
/* InputVar becomes an alias fo G_Var */
void SomeFunction(int &InputVar)
is wrong.
G_Var is not a global variable. You declare it two times to be local to main and SomeFunction. If you want to declare G_Var as global variable it has to be declared once at global scope, not inside of a function, and only access it by its name, not declaring its type twice.
But beside that the use of global variables is deprecated. Rather use parameter passing.
SomeFunction() isn't declared before the call to it in main(). Usually this would give you a diagnostic as the compiler don't know what SomeFunction() is.
InputVar is used as reference parameter, but also declared twice in SomeFunction. Here is a conflict.
I guess you never compiled this code before asking, which is a fault. It would have answered many questions of yours including the main one.
"Is the illustration on Aliasing in C correct?"
"Is the code correct and is working according to what is commented in the code?"
No, it isn't. The whole code is defective.
It gives the impression that the authors didn't knew how to either write correct C nor C++ code.

Selecting Static over Global. Why?

The output of the following code is 0.
int account=2;
int main()
{
static int account;
printf("%d",account);
return 0;
}
Why it picked static variable over global variable? Because what I understand is that both global and static variables are stored in the heap and not in function stack , right? So what method it uses to use select one over another?
If multiple variables exist with the same name at multiple scopes, the one in the innermost scope is the one that is accessible. Variables at higher scope are hidden.
In this case you have account defined in main. This hides the variable named account declared at file scope. The fact that the inner variable inside main is declared static doesn't change that.
While the static declaration on a local variable means that it is typically stored in the same place as a global variable, that has no bearing on which is visible when the names are the same.
Consider this small self explaining program:
#include <stdio.h>
int bar = 123; // global variable, can be accessed from other source files
static int blark; // global variable, but can be accessed only in the same
// source file
void foo()
{
static int bar; // static variable : will retain it's value from
// one call of foo to the next
// most compilers will warn here:
// warning declaration of 'bar' hides global declaration
printf("foo() : bar = %d\n", bar); // won't use the global bar but the
// local static bar
bar++;
}
void quork()
{
int bar = 777; // local variable exists only during the execution of quork
// most compilers will warn here as well:
// warning declaration of 'bar' hides global declaration
printf("quork() : bar = %d\n", bar); // won't use the global bar but the
// local bar
bar++;
}
int main() {
foo();
foo();
printf("main() 1 : bar = %d\n", bar);
bar++;
quork();
quork();
foo();
printf("main() 2 : bar = %d\n", bar);
printf("blark = %d\n", blark);
}
Output:
foo() : bar = 0
foo() : bar = 1
main() 1 : bar = 123
quork() : bar = 777
quork() : bar = 777
foo() : bar = 2
main() 2 : bar = 124
blark = 0
Just to clarify for future readers, global and static variables are not stored in heap or stack memory.
https://www.geeksforgeeks.org/memory-layout-of-c-program/
They will either be stored in initialized data or uninitialized data.
Thats not the main question here, which was answered by dbush, but it is a misunderstanding in the original question.
Short answer: encapsulation.
static describes both lifetime and visibility of a variable, and its meaning changes depending on the context. My opinion is that it is one of the more useful and important language features for encapsulation in c. Ignoring the complex relationship to extern, here's a simplified description:
static variables defined at the file level have program lifetime and compilation unit visibility. This means all functions in a .c file can access/modify the variable, but other .c files won't know about the variable. This is super useful for making sure variables used across functions with a compilation unit don't accidentally link with variables in other compilation units. Personally, I highly recommend all file variables to be static by default. Only remove the static specifier if you really want another compilation unit to have access to it (although a getter function may be safer)
Variables declared static within a block scope (most importantly function scope) have program lifetime, and scope visibility. That means it functions as if you declared the variable globally in the file, but only code within that block scope can see it. It also means from one call to the next, the variable does not get destroyed and state can be transferred from call to call.
One really important difference with static variables is that they are default-initialized to zero. This differs from all other variables in c, and is the reason your program prints the value 0. Often times with trivial programs we don't notice the difference because the stack hasn't been polluted with variables yet, but it becomes critical for any program of size.
The most common use for this that I have seen is to enable one-time initialization within a scope. They are also extremely useful for synchronization primitives like pthread_mutex_t. One time I even implemented a state-machine with function-scope static variable.
an example:
int started;//oops, anybody in the entire program can change this value, especially with such a common name!
static int lastCall;
int callCount(void)
{
// This is default-initialized to 0
static int functionStaticVariable;
//Increment each time I'm called
++functionStaticVariable;
//tell the outside world that I'm the one who was called last
lastCall = 1;
//return (a copy of) my internal state.
return functionStaticVariable;
}
char *getSharedMemory(unsigned int bytes)
{
// Here I cannot see functionStaticVariable, but I can see globalVariable
//functionStaticVariable++; // this would cause a compilation failure
// static pointer is default-initialized to zero (i.e. NULL)
static char *sharedMemory;
if(sharedMemory == 0)
{
// This block only executes once, the first time the function is called.
// Actually this is a nice side-effect because it means if the function is never called we don't clutter the stack with unused memory
// Although we will probably never free this memory
sharedMemory = (char *)malloc(bytes);
}
// tell the outside world that this function has been called
lastCall = 2;//valid
//Woah, this is such a bad idea, but actually does _not_ return memory that gets invalidated
return sharedMemory;
}
Hopefully you can see with this pattern you could protect a variable by placing it inside a function and doing optional things like acquiring a mutex-lock in order to allocate the memory. You could even implement the double-lock pattern this way.
I secretly wish that all C++ programmers learned good c encapsulation, because actually the language really encourages it. You can do an incredible amount by placing only functions that need to communicate with each other together in a compilation unit. In a non-OOP language, this can be very powerful.
Full details of static and extern are described by https://en.cppreference.com/w/c/language/storage_duration.
The pragmatic reasoning behind why innermost variable decaration should be the one used: you're not always in control of what's outside your code. You want to be able to write a function that certainly works. If other programmers (say, in a larger team) could break your code just by the way they name variables in other parts of the code, programming would be more of a pain than it is now.

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.

Putting variable declarations in a separate function in C

Is it possible to put the variable declarations in an external function? After reading from Wikipedia that:
an inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined.
I hypothesized that the following might work. It did not take long for the compiler to slap my fingers :(
inline void declaration(){
int a;
}
int main(){
declaration();
a=2;
return 0;
}
This may not be how it is done but if you want a basic idea of how you can think about what happens when you inline a function.
Imagine the compiler turning your code into something like this, then you see why it will not work.
int main(){
{
int a;
}
a=2;
return 0;
}
The call to declaration() is replaced by the contents of the function including brackets, thus int a; is declared in an inner scope and is not visible in the main function.
No, this is not possible.
What is possible, is to use a preprocessor directive #define:
#define VARBLOCK int a, b, c; char ca, cb, cc;
int main()
{
VARBLOCK;
a = 2;
}
This would be a bad practice. Also these would still be variables only available in the scope of function where it were placed, without values being shared.
No - as far as I'm aware an inline function must behave semantically equivalent to a non-inline function; it doesn't affect what counts as legal code. It's just an optimization.
In particular, you could have a variable called a in both functions, but they'd be separate variables on the stack.
(Even if you could do this, I'd suggest it would be a very bad idea in terms of readability.)
inline functions are usually just a function containing no more than about 4 lines and you would want the compiler to do the optimization you where talking about since it would be faster to do what the function does, rather than adding extra code.
Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently.
So there's nothing special with the inline function, rather than it might be handled differently by the compiler. They don't share their stack with any other function, which would be the only way for main to use a variable that is created in a different scope.
So my tip is; write your functions, and treat them as you usally should. Then when you are done, inline the short ones that you use a lot.
And if you really wanna create a variable in another function, allocate it on the heap in the function and return a pointer that you save and then set to 2 (your case). :) Just remember to free the memory!
You can do this, though:
#include <stdio.h>
int* GetMyIntAddress(void)
{
static int blah = 0;
return &blah;
}
int main(void)
{
printf("%d\n", *GetMyIntAddress());
*GetMyIntAddress() = 123;
printf("%d\n", *GetMyIntAddress());
return 0;
}
blah will be a global variable defined in the scope of the GetMyIntAddress() function.
If you add inline to the definition of GetMyIntAddress(), you are risking to get multiple independent instances of blah if the inline function is used in different modules (e.g. included from a shared header file).

Resources