0

For this code:

int main(void) {
  int a = 1;
  int b = 2;
  int* pa = &a;
  *pa = a + b;
  printf("%d", a);
}

At compile time the compiler calculates how much space it needs. We have 2 integers and one pointer. So it is 2*4 + 8 = 16. Then it specifies where the memory of a given variable is in relation to the start point address. pa is at the start point address and have length of 8 bytes. b is at start point address + 8 bytes and have length 4 bytes. a is at start point address + 12 bytes and have length 4 bytes.

Then go instructions for execution time:

  1. Ask OS to allocate 16 bytes and provide address for that space in memory. This will be start point address.
  2. put the binary representation of 1 at the location of a.
  3. put the binary representation of 2 at the location of b.
  4. translate relative address of a (start point address + 12 bytes) to its absolute location and put it at location of pa.
  5. get bytes at location a and bytes at location b, add them and then get bytes at location pa. Use bytes at location pa as an address and put there the calculated sum.
  6. print the bytes at location a converting them to decimal number first.
  7. free memory and let the OS know that program finished.

Is this a valid translation?

edit:

Let's assume a super simple compiler is used (no optimizations). All it cares about is a valid execution of C code.

marzelin
  • 10,790
  • 2
  • 30
  • 49

3 Answers3

4

That's pretty much one way to translate it(a), although local variables to a function usually get allocated on the stack rather than asking the OS for some amount of memory to store them.

Of course, with a smart compiler, there's enough information in that source code to simply optimise the whole thing down to:

int main(void) { putchar('3'); }

(a) The ISO C standard does not dictate how things are done under the covers, only that they behave in certain ways. Think of C as a virtual machine that implements the standard. How the VM does it is not really relevant, and certainly not mandated in any way other than the behaviour.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
3

As far as I read, yes it is a valid translation. No, it is almost 100 % certainly not the translation your compiler is going to produce. The C standard has the so-called as-if rule which means the compiler is free to produce any program whose side effects are as if the program were compiled for the so-called abstract C machine and run in there.

In practice, a compiler could for example produce the following program:

  • place the integer '3' into the register that is used as the first argument in function calls
  • call putchar
  • zero the register that is used as the return value
  • return from the main function

To an observer, the side effects of this program would be indistinguishable from those of your program: it prints 3 and returns from main with 0 as return value.

1

Step 1 The variables a, b and pa will be allocated in the stack. Therefore, there is no request to the OS for memory allocation -- you'll just use the stack, which is controlled by the process itself. Maybe it won't ask for 16 bytes -- 4 bytes are enough, since you're effectively using variable a. And even that one is constant, so instances of a can be replaced by 1.

Step 4: This step may be completely skipped by the compiler, since you are not using the value of pa until it is reassigned in the next step.

Step 6: Push the two arguments (%d\0 string and the value 1) into the stack and call function named printf. No idea if it outputs into a terminal -- maybe stdout is redirecting into a file?

In the end it's impossible to know exactly what instructions will be produced from that source code. Depends on the architecture, operating system/OS version, compiler/cc version, compiler flags...

João Neto
  • 1,732
  • 17
  • 28