3

Consider this:

    main()
    {
      int i = 1;
      fork(); fork(); fork();
      printf("%d ",i);
    }

The output of the above code is:

1 1 1 1 1 1 1 1

That is, at the end there are 8 (2^3) processes reaching the printf() line. Now consider the code below:

    main()
    {
      int i = 1;
      fork() && fork() || fork();
      printf("%d ",i);
    }

Initially, I thought there'd be no change in the output because the results of the comparisons using && , || are not being evaluated by a control statement like if or while. That is, they're being discarded. However, The output of this code is:

1 1 1 1 1

Meaning, at the end there are 5 processes that reach the printf() line.

My question: What does this line do

 fork() && fork()||fork();

Definitely, something has changed. I've never contemplated using comparison operators like && , || without control statements like if, while to evaluate the result of the comparison and accordingly take some action. I thought, without these control constructs, the comparison operators are meaningless; they'd simply return 1 or 0 without anything being done about it.

Clearly, I'm mistaken, and am totally unaware of this usage of the operators.

sanjeev mk
  • 4,276
  • 6
  • 44
  • 69
  • 3
    Perhaps writing code that is sensible would be a good start – Ed Heal Feb 17 '14 at 15:36
  • @EdHeal This was a puzzle. – sanjeev mk Feb 17 '14 at 15:42
  • I don't see how this is a duplicate. The question is not about fork(). As it turns out , it is about something called, "short circuiting of operators". A person who has never heard of this term before cannot look this up (which is the case, this time) – sanjeev mk Feb 17 '14 at 15:44
  • @sanjeevmk - the titles might be different, but it is a duplicate because the core of the question (using logical `&&` and `||` operators on a `fork()` call) and the answers (how to evaluate this statement) are the same as yours. – Mike Feb 17 '14 at 15:59
  • I've revised the title of the duplicate question so that it better reflects what is inside (and specifically mentions && and || in the title). – Jonathan Leffler Feb 17 '14 at 18:08

2 Answers2

3

fork() returns the PID for a child process if it’s returning in the parent, or 0 if it’s returning in the child. Logical operators short-circuit in C, so a && b doesn’t evaluate b if a is 0, and a || b doesn’t evaluate b if a is not 0.

So you fork once. Two processes. The right side of the && only gets evaluated in the child. Three processes. The right side of the || gets evaluated in the same child again. Four processes. But wait! && binds tighter than ||, so the parent process also forks again, for a total of five processes.

Ry-
  • 218,210
  • 55
  • 464
  • 476
1

Even though it's not part of a conditional check, the following statement:

exp1 && exp2 || exp3;

Would still evaluate per boolean expression evaluation rules. In this case, if exp1 is false (0), then exp2 will be skipped since exp1 && exp2 is already determined to be false. And if exp1 && exp2 is true (not 0), then exp3 will be skipped since the whole expression is then determined to already be true.

lurker
  • 56,987
  • 9
  • 69
  • 103