2
\$\begingroup\$

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.

\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$

Yes, it is just a matter of interpretation. No, this is not best practice for real-life applications but who cares about sensible programming when codegolfing anyways?

main(int a, char **argv)
{
  int d = *(int*)argv[1]; //<-- Is this allowed?

I do not program in C, but I wonder whether a typecast (I suppose) is really necessary. Could you not just as well write:

main(int a, int **argv)
\$\endgroup\$
1
  • \$\begingroup\$ To the second part: This works as well. Note that this was also included in the Question: main(a,v)int **v;{....}, which is a even shorter form than main(int a,int **v){....}. In C, the default type is int this is why declarations that don't specify a explicit type (such as auto, static, no return type, arguments without type) are of type int. This is why main(a,v)int **v;{....} sets the return type of main to int as well as the type of a to int. (This isn't legal C-Code anymore, it was used in pre-ANSI times. But it is shorter and still works on many systems). \$\endgroup\$ Aug 28 at 10:15
0
\$\begingroup\$

No

AFAIK, this isn't a natural way to take input in the aforementioned languages (or any language that I know of). Surely a (full) program shouldn't need another program to generate the proper input format?

\$\endgroup\$
2
  • \$\begingroup\$ "Surely a program shouldn't need another program to generate the proper input format?" Writing or reading from a specific address is allowed. Or from a register. Or sometimes only functions are posted without any way to start the program. So the answer this "question" is: No, you may need a program to generate the correct input. \$\endgroup\$ Jul 20 at 11:40
  • \$\begingroup\$ I don't think that's a good general principle, for example we allow length prefixed input or input as byte values both of which would require a second program to generate the input \$\endgroup\$
    – mousetail
    Aug 21 at 20:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .