I need to run many times a code of mine, changing a variable defined in an header file.
I wanted to write a bash script that compiles (through makefile) and runs
./myprogram some_value
is there a way to use what I recover from atof(argv[1]) inside an header I'm including inside myprogram.c ? (An header shared between many other files, containing the values for the parameters I'm using in my code)
In that header I'd have something like
float the_parameter;
that I want to initialize to atof(argv[1])
Firstly, put a declaration of the variable with extern in your header file.
extern float the_parameter;
Then, in one of your source file, declare the variable without extern and initialize that.
#include <stdlib.h>
float the_parameter;
int main(int argc, char* argv[]) {
if (argc > 1) the_parameter = atof(argv[1]);
/* other code */
}
Related
I have a header file , "temp.h" ,and several ".c" files which has "#include <temp.h>" header statements in each of them. And I define a global static char array in "temp.h" file as follows:
temp.h
static char buffer[1000]={'A','B','C','\0'};
main.c
...
#include <temp.h>
int main()
{
strcpy(buffer,"xyz");
printf("\nBuffer : %s",buffer);
func();
return 0;
}
other.c
...
#include <temp.h>
int func()
{
printf("\nInside func(), buffer : %s",buffer);
return 0;
}
and I compile all files with following command:
gcc -o output.o main.c other.c
And I get no errors... and when run the "output.o" program ,
I expect a result like this:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : xyz
but I get:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : ABC // doesn't get updated buffer content- why?
Why when I change the contents of a "(supposedly)global" static char array in one file inside any function scope (main or anyother), this change doesn't get reflected to all this char array's future references from any other file later, but instead in each file((or maybe inside in each function) its content is preserved??
How to make such that, I can use a specific part of char array (memory region) which is GLOBALLY accessible from all "files" and in their functions, and all references get correct readings?
thnx
With your current approach you have two copies of the array. Instead you need to declare the array in temp.h (with extern instead of static) and define it elsewhere, for instance in in temp.c:
temp.h:
#ifndef TEMP_H
#define TEMP_H
extern char buffer[1000];
#endif
temp.c:
#include "temp.h"
char buffer[1000] = "ABC";
You can also probably find a more descriptive name than temp for the module. It is also a good idea to add a prefix to the buffer variable, e.g. temp_buffer so that you avoid potential name clashes and make it easier for yourself and others to find where the array is declared.
Ok...GOT IT!... now I solved!
In a singly included header file (( which is temp.h in question )) u must write:
extern char buffer[];
Note: single inclusion of this temp.h file can be achieved by "#ifndef-#endif" pairs in other ".c" and ".h" files of the compilation.
And next, include only in one of the files the following statement of definition:
char buffer[1000];
I hope this solution helps some guys.
I am attempting to define a set of global variables which will configure my device, about 10 in a dedicated .c file, that will be changed on a regular basis at compile time (as per device requirements), I want these to be in this separate file so they can all be changed easily. These variables are then called throughout my program in various files. And are never changed only read. The problem is that my compiler (XC8 for PIC MCU's) doesn't define the variable, as it can only see that one use of the variable in the file, even though it is called with extern throughout the program.
config.h
unsigned int Global_A;
unsigned int Global_B;
void config(void);
config.c
void config(void)
{
unsigned int Global_A=987;
unsigned int Global_B=123;
}
prog_a.h
extern unsigned int Global_A;
extern unsigned int Global_B;
unsigned int var_A;
void prog_a(void);
prog_a.c
unsigned int var_A=0;
void prog_a(void);
{
var_A=Global_A+Global_B;
}
main.c
#include config.h
#include prog_a.h
void main(void)
{
while(1)
{
config();
prog_a();
}
}
as a result, the equivalent var_A is always 0, as the compiler has done away with config.c as it cannot see the variable called again.
I'm assuming the answer is very obvious to those more versed, but I can't find anything online. I have not had any trouble with using extern and globals before when they are used in the file the are defined in. But I could just be using it wrong fundamentally, so feel free to berate me.
Thanks in advance.
p.s if it wasn't obvious this is an example code to illustrate my problem.
Your function config declares two new variables in the scope of the function (their names hide those of the global variables). They don't exist anywhere outside of it, and assigning a value to them does nothing. If your goal was for it to initialize the globals, you need do this:
// config.h
extern unsigned int Global_A;
extern unsigned int Global_B;
void config(void);
// config.c
unsigned int Global_A;
unsigned int Global_B;
void config(void) {
Global_A=987;
Global_B=123;
}
With extern keyword it it necessary to declare the variable once (preferably in a header file) define it once in a .c file that has visibility to the declaration statement. That is it. Where the extern defined variable is necessary, #include the header file in which the declaration statement occurred.
Also note it is important also to define extern variable(s) in global scope (i.e. not in a function).
config.h:
#include "prog_a.h"
//unsigned int Global_A;
//unsigned int Global_B;
void config(void);
main.c
#include config.h
#include prog_a.h
...
//suggest defining these here:
unsigned int Global_A=0;//define outside of function
unsigned int Global_B=0;
...
config.c
#include "prog_a.h"
...
void config(void)
{
Global_A=987;
Global_B=123;
}
Your global variables are all of type int, so why not just use #define?
Change file config.h to
#define Global_A 789
#define Global_B 123
You do not actually have to declare any int variables to hold those values, plus, they will be const and unmodifiable.
That's they way that we did it "back in the day", but in the last decade or two, I see more and more actually storing these configuration values in an external text file
It can be a .INI, or XML or JSON, etc, etc, that is up to you.
You just create different files, let's say Singapore.ini and Paris.ini and Auckland.ini, etc, each containing a key/value pair.
e.g
time_zone = X
population = Y
etc, etc
Then, at the start of your main, read the file in and store the values -but not in globals, which are frowned upon, these days. Read them into variables which are local to config.c, and have config.c/h provode methods to read their values, e.g GetTimeZone() and GetPoulation(), etc
Don't worry about any code size or run time impact of this, as any decent compiler will in-line these function calls.
One advantage to reading "global" configuration values in an external text file is that you only need to build your software once. You do not need to rebuild and have an executable for each configuration, which the road that you are currently heading down.
Firstly, this makes it easier to test your software (especially automated test), by merely editing the text file, or supplying a new one.
Also, since you only have a single executable, you can ship that to all of your users/customers, and give each a tailored config file. You can totally control & change the functionality of your software just by changing the config file. You might want to think about that.
I am looking for a way to find the name of the executable file which runs it. meaning that if I have a file called program which runs something I would like to get its name.
Using __FILE__ does not suite me since I need the executable name not the C files name which contains the code.
I am wondering if there is a gcc macro which can help me or a built in function which I couldn't find.
EDIT:
Also using argv[0] is not appropriate since I need to call the function not only inside main.
And passing the argv[0] parameter to all the functions that might need this parameter also isnt acceptable since it will be used in the entire system (I need to hash by it).
int main(int argc,char* argv[])
{
printf("%s",argv[0]);
return 0;
}
The first argument(argv[0]) contains the name of the program which is being run.
The standard definition for main() in C is:
int main(int argc, char **argv)
argv[0] contains the name of the program as executed.
From main, pass argv[0] to wherever you might need the program's name.
Or if a lot of functions need it and you want to avoid passing it around too much, assign it to a global variable.
You asked for macros as a solution, but they are expanded at compile time. And since the name of the executable file can be changed after compilation, what you want cannot be determined at compile time, so macros are out of question.
Often remembering argv[0] from main will be quite sufficient.
If this is not the case -- for example if you're a shared library, or if you worry that your caller started you with a faked argv[0] (this is possible but unusual), you can, on POSIX-compliant systems with a mounted /proc, use readlink to resolve /proc/self/exe and get a path to the main binary of the running process:
#include <limits.h>
#include <unistd.h>
// Note that readlink does not null-terminate the result itself. This
// is important if the link target contains null bytes itself, I suppose,
// but it means that you have to take care that the null-terminator is
// placed yourself if you're going to use the file name as a string.
char buf[PATH_MAX] = { 0 };
readlink("/proc/self/exe", buf, PATH_MAX);
And on Windows, there is the GetModuleFileName function:
#include <windows.h>
TCHAR buf[MAX_PATH];
GetModuleFileName(NULL, buf, MAX_PATH);
The startup name is given via main()'s argv[0] and can be considered constant.
So why not make it available through out the program using a global reference to it.
progname.h
#ifndef PROGNAME_H
#define PROGNAME_H
extern char * progname;
#endif
main.c
#include "progname.h"
char * progname = NULL;
int main(int argc, char ** argv)
{
progname = argv[0];
...
}
Access it from any where like so
module1.c
#include <stdio.h>
#include "progname.h"
void f(void)
{
printf("progname='%s'\n", progname ?progname :"<not set>");
}
I needed to define several variables (Global variables), which are going to be used by many .c files. Variables like String array, File Pointer, Int etc.
Situation : FileX.h
Different c files(FileA, FileB, Filec, FileD) compiled with -c option individually(FileX.h have been included by all) then some of the files compiled again by combining them. When these are compiled individually No error pop up, but When they are compiled in a group (FileA.o, FileB.o and FileC.o), It pop ups Error. Is there any way to solve it. I thought of solving this with extern but seems this would also pop up error also.
Any suggestion please ?
I don't want to define variable in each .c file
I have String array so i don't want to define them every file
I'm assuming you get a multiple definitions error because your header looks like
global_variables.h
int global_a = 10;
int const global_b = 20;
What you need is
global_variables.h
extern int global_a;
extern int const global_b;
global_variables.c
int global_a = 10;
int const global_b = 20;
Edit: Further explanation:
Now in all your other files that need the global variables all you need is:
other_file.c
#include "global_variables.h"
void some_func(void){
global_a = 5; /* ready to use */
}
other_awesome_file.c
#include "global_variables.h"
/* and now you can use all globals */
I have two files:
hudwidgets.c
#include "osd.h"
#include "osdadd.h"
#include <stdio.h>
struct TextSize tsize;
char buff[50];
void hud_draw_lin_compass(int cx, int cy, int tick_maj, int tick_min, int range, int heading)
{
.. important code that uses buff ..
}
hud.c
#include "hudwidgets.h"
#include "hud.h"
#include "osd.h"
#include "osdadd.h"
.. some code ..
void hud_rc_plane_single_frame()
{
fill_mem(0x0000);
if((frame / 50) % 2 == 0)
{
get_next_warning(buff);
}
.. some more code ..
}
The problem I have is that when I try to compile this, the compiler complains of no buff defined, but when I try to define it, the linker complains of two buff variables. Catch-22. To this end, I am asking two questions:
how to fix this, and;
if it is possible to use the same variable thus saving memory because only one variable needs to be allocated (working with a memory constrained microcontroller.)
You need this in the top of hud.c, and any other .c file you use them from:
extern struct TextSize tsize;
extern char buff[50];
The extern keyword tells the compiler that the "actual" variables already exist, in some other unit (file), and the linker will fix it all up for you in the end.
If you're doing this on a large scale in a project, consider how you might encapsulate globals in one place, and create a shared .h file that declares these things as "extern" for all the places that you use them from.
use "extern char buff[50];" in the files where you have not initialized the buff and want to use it. This tells that the declaration is done in other files and you are using it in this file.