dreamcrash
dreamcrash

Reputation: 51623

The reason behind this Output

I have made an test where it have appeared something like this:

char* trim(char* strr, char* str1) {
  char* s = strr;
  while(*str1 == 32) str1++;
  while( (*str1 != 32) && (*str1 != 0) )
        *s++ = *str1++;
  *s = 0;
  return strr;
  }

int main(void) {
  char str[20] = "???";
  char str1[20] ="    bcd  \0";

  printf("(%s)\n(%s)\n", str, trim(str, str1));
  return(0);
}

The question was: What the above code will print and why? I got a clue on the output and why but I would like to hear from more experienced people on the subject.

At a first glance it looks like it will print:

(???)
(bcd)

but in reality the output produced is:

(bcd)
(bcd)

Upvotes: 2

Views: 119

Answers (3)

TrueY
TrueY

Reputation: 7610

The last argument is evaluated first and pushed to the stack first. But the order of evaluating the arguments is not definite.

I crated a simple code:

#include <stdio.h>

char *go(char *s) { *s = '0'; return s; }

int main() {
    char str[] = "xyz", str1[] = "abc";
    printf("(%s)(%s)\n", str, go(str));
    printf("(%s)(%s)\n", go(str1), str1);
}

Output:

(0yz)(0yz)
(0bc)(0bc)

You can analyse the assembly output with this gcc command line:

gcc -c -g -Wa,-a,-ad x.c >x.lst

If You add -O2 the order is the same, but the go() function become inlined.

Hmmm... I have learned something again! Thanks for it!

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490728

[Edit: removed previous answer, which @Nigel Harper was nice enough to be polite in pointing out was complete nonsense.]

The arguments to printf (all the arguments) are evaluated in some unspecified order before execution of printf itself begins. Therefore, by the time printf starts executing, both str and (importantly) trim(str, str1) have been evaluated.

Since the trim(str, str1) modifies the memory that str points at, by the time printf itself is executing, the memory pointed at by str will have been modified to contain the bcd (and obviously, the pointer returned from trim(str, str1) will as well).

Therefore, regardless of the order in which the two arguments are evaluated, both outputs will be bcd.

Upvotes: 2

unxnut
unxnut

Reputation: 8839

You are overwriting into strr within the function which is str in your call. Since it is being passed by reference, the change is reflected back into the calling function. printf will get the evaluated copy of str (same in both arguments).

Upvotes: 1

Related Questions