TL;DR: Is int d = *(int*)argv[1];
allowed to obtain a integer input?
A special case of this question: Can numeric input/output be in the form of byte values?
This is mostly for C, C++, assembly and languages with similar properties.
Lets say the programs needs a integer or floating point as input. Is it legal to obtain this value by interpreting the binary representation of argv[1][0]
...argv[1][n]
as integer of floating point? In C you can do that with a=*(int*)argv[1];
A possible problem is that this makes it harder to input numbers where some bytes of it, except the highest byte, are 0
. In C strings are terminated with '\0'
or 0
, and therefore argv
on most OSs. So to input a number which has a 0-byte in it you have to use more than 1 argv
argument.
How argv is filled in memory
On my Linux Debian AMD64, argv
is in memory like this.
V--- argv[0] points here V--- argv[1] points here
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| . | / | a | . | o | u | t |\0 | A | R | G | 1 |\0 | A | R | G | 2 |\0 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
^------Program name---------^ ^---Argument 1--^ ^---Argument 2--^
Interpret this 4 bytes as integer:^-----------^
Edit: This is the same as in /proc/self/cmdline
on Linux.
argv -> Input mapping
This is how it works on my machine with bash. Probably different on other machines.
./myProgram '' '' '' '' # Read as 0x00000000 (4 times a terminating 0 character)
./myProgram ' ' '' '' # Read as 0x00000020 (0x20 is the ASCII value of ' ')
./myProgram '' ' ' '' # Read as 0x00002000 (2 times 0 byte, ' ', 0 byte)
./myProgram ' ' ' ' # Read as 0x00200020 (0 byte, ' ', 0 byte, ' ')
./myProgram ' ' '2' # Read as 0x00320020 (0 byte, '2', 0 byte, ' ')
./myProgram '1234' # Read as 0x34333231 ('4', '3', '2', '1')
However, this will not work
# Will not be read as Read 0x00200020, what you might expected, but as 0x00002020.
./myProgram "$(echo -e ' \x00 ')" '' '' ''
# (note, bash just ignores the \x00 altogether, but it wouldn't work anyway).
Example Program
Lets say the task is to double a number. Can i do this?:
main(int a, char **argv)
{
int d = *(int*)argv[1]; //<-- Is this allowed?
printf("%d",d*2);
}
Or in a more golfed version: main(a,v)int **v;{printf("%d",2**v[1]);}
, which is shorter than main(a,v)int **v;{printf("%d",2*atoi(v[1]));}
which reads argv[1]
as a ASCII string.