Will the command line arguments be "passed twice"? [duplicate] - c

This question already has answers here:
How do command line arguments work?
(3 answers)
Closed 5 years ago.
I am trying to understand how command line arguments work in details.
This is what I think happens:
When you compile a source code that contains the main() function in C, the generated object file will be linked with the CRT, and the entry point for the program will be the _start() function (which exists in the CRT), and _start() will call main().
Now when you run your program and pass it some command line arguments, the command line arguments will be passed to the _start() function, and then _start() will re-pass the command line arguments to main().
Am I correct?

Am I correct?
Yes and no:
The _start() function is not a C function but an assembler function. The reason for this is that the CPU is not in a "state" which is required by C programs so the _start() function also has to set up the CPU for executing C code.
One difference between the "state" required by C programs and the "state" of the CPU when _start() is called is the way arguments (here: command line arguments) are stored.
Under Linux (at least 32 bit - I don't know about 64 bit) you actually have an array that later represents argv. _start() has to calculate the location of argv and then pass the calculated value to main().
Under Windows there is a function that returns the entire command line as pointer to a single string (const char *)! The _start() function has to call that function and then to split the string into parts that will later become argv...

Related

How do I correctly execute a C program with arguments? [duplicate]

This question already has answers here:
What are the arguments to main() for?
(5 answers)
What are the valid signatures for C's main() function?
(5 answers)
Closed last month.
When I try to execute my program with an argument, it only returns a single result, regardless of the argument. It worked as expected when I did not attempt to implement arguments.
The program and it's output
I'm just now learning C, and I've written a Collatz Conjecture evaluator to review the syntax I've learned. Other sources say to just add an argument in the main method and then execute a.out with your argument after. So far that hasn't worked as expected. Am I implementing arguments incorrectly? Is the body of the program itself erroneous?

No way for a C user-defined function to find out the total number of arguments passed to it? [duplicate]

This question already has answers here:
How to count the number of arguments passed to a function that accepts a variable number of arguments?
(13 answers)
Closed 1 year ago.
This web page says:
C supports variable numbers of arguments.
Okay, I got that.
But there is no language provided way for finding out total number of arguments passed.
Really? Is that true?
Apparently it is true because in every example that I have seen of a function with a variable number of arguments, there is always an argument that specifies the number of arguments, e.g.,
int sum(int numargs, ...)
Isn't that cheating?
Isn't the whole point of a function with a variable number of arguments is for the function to figure out how many arguments are provided? (Not be told how many arguments are provided)
Is there no way to create a function that sums an arbitrary number of integers, without the caller telling the function how many integers there are? (And without forcing the caller to append some sort of sentinel value like NULL onto the end of their argument list)
Is this possible:
int sum(...)
To really understand why this is true, and why there can only be workarounds like providing sentinel value or format string (like printf does), you need to look at how C functions are compiled.
https://en.wikipedia.org/wiki/X86_calling_conventions
If you look at the assembly that is generated (try gcc -S if you are on a *nix type OS), you will see there is no information regarding how many arguments are being passed, and it is up to the code of the function to pull them off the stack (usually, some conventions pass some arguments via registers).
As a matter of fact, not only the count, but the type information is lost in compilation as well.
Unlike other, newer languages, all C function has to access parameters is a stack pointer, from there it is up to the function to decide what to pop off the stack and how to interpret it.
The variadic syntax in C just allows you to bypass the rigid argument checks during compilation, and give back some of the assembly level freedom regarding function arguments.

How does C parse command line arguments?

I'm curious as to what C does exactly to parse command line arguments. For example, assume I have a program named myProgram that takes in two arguments like this
./myProgram arg1 arg2
If I were to call
./myProgram arg1$'\0otherstuff' arg2
arg1 and arg2 would still print if we were to print argv[1] and argv[2], ignoring $'\0otherstuff', but where does it go? Is it store in memory behind arg1? Could it potentially overwrite any buffer? How is arg2 read if there's a null character before it?
Converting ./myProgram arg1 arg2 into a C style int argc, char *argv[] is done by the operating system or by shell (it depends). C does not parse the arguments, you parse the arguments in C. C is a programming language, not entity. The form int argc, char *argc[] is used in the C programming language as the arguments passed to the main function, but other programming languages may use a different form, for C see main_function.
In linux, one may use execve system call to specify arguments passed to a function. Parsing from the form ./myProgram arg1 arg2 to execve arguments is done by the shell (e.g. bash), which constructs argv array and passes arguments to execve call.
Your shell is probably ignoring the part $'\0otherstuff', because under POSIX flename cannot contain the NUL character (assuming your shell is POSIX compatible).
When calling an executable, your OS kernel will take the additional arguments (as plain text) and pass them into the program memory.
Before the main function is called, a small code is executed, which passes the given arguments to the actual main function in C.
Experimenting with bash (version 3.2.57(1)-release (x86_64-apple-darwin17)) suggests that the “otherstuff” in your example is not passed to the program. When a program is called with the command line you show, the memory pointed to by argv[1] contains “arg1”, then a null character, then “arg2”. Thus, the null and “otherstuff” in your command line has not been passed to the program.
(Hypothetically: If the shell were to pass it to the program, I would expect it would pass it in the memory continuing from that pointed to by argv[1], and there would be no danger of it overwriting any buffer. If the shell were designed to tolerate an embedded null character in an argument, I expect (based on how we design things) that it would treat the argument as a complete string and provide the necessary space to hold it.)
The fact that the argument prior to “arg2” contains a null character is irrelevant to the handling of “arg2”. After initial processing of the command line, the shell does not treat the line as one string. It has divided it into words or other units and handles them with its own data structures. So the presence of null characters in prior arguments has no effect on later arguments.
Additionally, it may not be possible for the shell to pass an argument containing an embedded null character. The routines typically used to execute a program, such as execl, accept the arguments as null-terminated strings. So the embedded null terminates the string, and the execl routine never passes anything beyond the null character.

C - array address used to execute code

If the following array contained shell code in a C program on a LINUX machine
char buf [100]
then how does the following execute this shell code :
((void(*)())buf)()
Simple. It casts buf to a pointer-to-function taking no arguments and returning void, and then invokes that function.
However, that probably won't work since the page containing buf is highly unlikely to be marked as executable.

command line argument in C [duplicate]

This question already has answers here:
Reading command line parameters
(4 answers)
Closed 8 years ago.
I was doing my programs Python, so not much familiar with C.
I am doing a program on creating a binary tree in C. I am using an "insert" function created by me . The goal is that for typing "insert " in command line, the function should work. But I have not much idea regarding how to get and parse command line arguments in C. Can anyone help?
http://www.cprogramming.com/tutorial/c/lesson14.html
int main( int argc, char *argv[])
This should be the declaration of your main function. argc is the amount of arguments. argv[] is an array that contains each command-line argument as a string, the program name is argv[0] so the first argument will be argv[1]. I'm not a C programmer, so this might not be good info, I highly recommend checking out the link.
Use a library to handle the low-level details, such as getopt. The code is much more involved than with Python's argparse or getopt, but is similar in concept. (the wikipedia article to which I linked contains example C code using getopt)
Command line arguments are passed during run time.
You have to specify the number of arguments and also a char pointer to point to these arguments. This is done in main() syntax itself.
Void main(int argc, char* argv)
In order to compile and generate an executable in CC compiler,
cc -o exec_name program_name.c
In order to run,
exec_name arg1 arg2.........
It is to be noted that the exec_name is also considered as an argument

Resources