Picking up value of __attribute__ ((constructor)) function in main - c

I am trying to create a before-main evaluation like this:
int evaluate(int argc, char** argv) __attribute__ ((constructor));
int evaluate(int argc, char** argv)
{
int result = atoi(argv[1]);
if (result == 0)
return 1;
else
return 0;
}
int main(?????)
{
if (????? == 0)
printf("Wrong number.");
else
printf("It is 1!");
}
Is there a way to do this? I am doing this purely to get myself more familiar with C, passing command line arguments and using pre-main functions.

This is very platform-dependent. The glibc dynamic loader passes the argc, argv, and envp to ELF constructors, so you can access the program arguments in this way. To my knowledge, this is an undocumented dynamic loader feature, so you probably should not rely on this behavior.
For the result of the check, you will have to write it to a global variable (or record it in some other global data structure). The implementation discards the

Related

How to call main() from other functions in C

I was going through the difference in C and C++ and I found a tricky point. Can you please elaborate the below points:
In C, we can call main() Function through other Functions.
In C++, we cannot call main() Function through other functions.
How to call main() from another function and what is the use case of it?
#TrevorHickey hit the nail on the head (where did his answer go?) - C++ forbids calling main from within a different function (for good reason)... Not that any compiler is likely to stop you (I don't think most of them care).
An obvious workaround would be to move main's functionality into a container function and call it from there, as suggested by #KlasLindbäck.
i.e.
int my_application(int argc, char const * argv[]) {
// do stuff
return 0;
}
int main(int argc, char const * argv[]) {
return my_application(argc, argv);
}
Another "hack" that probably only works because compilers let you call main anyway (As also pointed out by #KlasLindbäck in the comments), would be to use function pointers. i.e.
int main(int argc, char const * argv[]) {
// do stuff
}
// shouldn't compile... but hey, you never know.
int (*prt_to_main)(int, char const* argv[]) = main;
void test_run(void) {
prt_to_main(0, NULL);
}

how string (command line) are stored in char**argv and int *argv?

First snippet:
#include<stdio.h>
int main(int argc, char **argv)
{
int i;
for(i=1; i<argc; i++)
printf("%s\n", argv[i]);
return 0;
}
load time input :
./a.out devang samir
output:
devang
samir
Second snippet:
#include<stdio.h>
int main(int argc, int *argv)
{
int i;
for(i=1; i<argc; i++)
printf("%s\n", argv[i]);
return 0;
}
load time input :
./a.out devang samir
output:
devang
samir
in both case, i got output same, but why?
in first case how the strings (command line ) are stored in char** argv ?
in second case how the string (command line ) are stored in int * argv...?
The C11 standard specifies the function signature for main() in chapter §5.1.2.2.1 as
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;[...]
and regarding the constrains,
If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings,[...]
Then, in your second case,
int main(int argc, int *argv)
char* and int ( for argv[n], in general) are being different types altogether (i.e, not compatible type), your second program invokes undefined behavior.
To elaborate, in case of the functions without having a prototype, the parameters passed to the function while calling should exactly match the type of expected arguments.
Quoting the standard, chapter §6.5.2.2
[...] If the function is defined with a type that does not include a prototype, and the types of
the arguments after promotion are not compatible with those of the parameters after
promotion, the behavior is undefined.

how to use cmd passed arguments in other function?

we declare main() as
int main(int argc, char *argv[])
and pass some argument by command line and use it
as argv[1], argv[2] in main() function definition but what if i want to use that in some other function's definition ?
one things i can do it always pass that pointer char** argv from main() to that function by argument. But is there any other way to do so?
Just pass the pointer?
int main(int argc, char** argv) {
do_something_with_params(argv);
}
void do_something_with_params(char** argv) {
// do something
}
Or if you mean passing single arguments:
int main(int argc, char** argv) {
do_something_with_argv1(argv[1]);
do_something_with_argv2(argv[2]);
}
void do_something_with_argv1(char* arg) {
// do something
}
void do_something_with_argv2(char* arg) {
// do something
}
In order to make data available to other functions, you need to pass it as a parameter, or make it available through a global (not recommended) or a static variable.
static char** args cmd_args;
static int cmd_arg_count;
int main(int argc, char** argv) {
cmd_arg_count = argc;
cmd_args = argv;
do_work();
return 0;
}
void do_work() {
if (cmd_args > 1) {
printf("'%s'\n", cmd_args[1]);
}
}
The best approach is to make a function that parses command line parameters, and stores the results in a struct that you define specifically for the purpose of representing command line arguments. You could then pass that structure around, or make it available statically or globally (again, using globals is almost universally a bad idea).
one things i can do it always pass this value from main() to that function by argument. But is there any other way to do so?
No. Passing the argc and argv to other functions is perfectly valid.
int main(int argc, char *argv[])
{
typedef struct _cmdline_arg_struct {
// all your command line arguments go here
}cmdline_arg_struct;
/* command line arguments - parsed */
cmdline_arg_struct *pc = (cmdline_arg_struct *) malloc(sizeof(cmdline_arg_struct));
if (parse_cmdline_args(&pc, argc, argv) == PARSE_FAILURE) {
usage();
return 0;
}
/* Now go through the structure and do what ever you wanted to do.. *?
}
You could have code in main() to store the values in non-local variables, and then refer to those variables from other functions.
If you really need to, store them in globals.
but what if i want to use that in some other function's definition?
You mean have another set of parameters for main? That's not possible, because main is defined in the C standard as either
int main();
or
int main(int, char*[]);
And it makes sense: The first parameter tells you the number of parameters given on the command line, the second contains the array of pointers to those parameters.
It's your responsibility to make sense of those parameters and pass them to other functions. Use string conversion functions if you need to make them numbers.

call of a function in another function in C

I was wondering how I could call a function in an other function in C.
For example, I created the function :
void speed (int argc, char** argv)
from a hyperterminal, I type 1 or 2 and I get something written on the hyperterminal.
In another function called:
void menu (int argc, char ** argv)
I want to call the previous function: speed(...). I dont know what to fill in for ....
thanks
jim
void menu (int argc, char ** argv)
{
speed(argc, argv); // this is how you call a function
}
For this to work either speed needs to be defined above menu, or a declaration of it needs to be before it or in a header. Declaration of speed looks like
void speed (int argc, char ** argv);
What Franco was talking about are called function prototypes. C parses (or compiles) your code from top down, so if it hits your call to speed before it hits your declaration of speed it complains. To workaround this, you need to create a function prototype as a forward reference to the function. Generally, it is good practice to write prototypes for all your functions at the top of your code, or in another file (aka the header file) and #include it.
/* helloworld.h */
void speed (int , char **);
void menu (int , char **);
/* helloworld.c */
#include "helloworld.h"
void menu (int argc, char **argv){
speed (argc, argc);
}

Passing arguments to a C program

I was writing a C program where I use 6 variables a,b,c,d,e,f
a,b,c are constant values which I should pass as an arguments from the command line.
d,e,f are going to be size of arrays of a structure.
typedef struct
{
blah blah
} ex;
ex ex0[d];
I am very confused about how to pass all these as argument. Right now I have hard coded these values,which apparently I should not be doing.
This should get you started:
int main(int argc, char* argv[]) {
// argc - number of command line arguments
// argv - the comand line arguments as an array
return 0;
}
All params you pass to the program are stored in second argument of main function
int main(int argc, char* argv[]) // or int main(argc, char** argv)
so you can easily access 4th parameter by argc[3]. But it is not int, it is string, so you need to parse it. There are standard libraries for both taking you actual parameters from argc and parsing them for type you need. But in casual progrmas there is no point using them, so your code may look like this:
typedef struct
{
blah blah
} ex;
int main(int argc, char* argv[])
{
ex ex0[(int)argv[3]]; // i am not sure if it works on pure C, so you can try int atoi(char *nptr) from stdlib.h
}
Use command line arguments
int main(int argc, char* argv[]) // or int main(int argc, char **argv)
{
// argc is the argument count
//argv : The array of character pointers is the listing of all the arguments.
//argv[0] is the name of the program.
//argv[argc] is a null pointer
}

Resources