user3655508
user3655508

Reputation: 21

why does the value of the return variable change?

I'm working on a linux proxy program and I'm stuck with this problem. This is the code I'm struggling with.

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){
  printf("%d\n", n);
  Rio_writen_w(serverfd, buf, n);
}

This is the wrapper function of 'Rio_readlineb_w'

ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
{
  ssize_t rc;
  if((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0 )
  printf("Rio_readlineb error");
  printf("%d\n", rc);
  return rc;
}

Variable 'rc' means the number of characters read by the rio_readlineb function. Using the printf inside the wrapper function, I checked that rc is exactly the number of characters read. However, the variable 'n' of the upper while statement is always 1. I can't find out what's wrong. Do you think the return value changed some how?

Upvotes: 0

Views: 173

Answers (3)

John Bode
John Bode

Reputation: 123468

n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0

is parsed as

n = (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0)

since = has lower precedence than >, so n gets the result of the comparison, which will be either 0 or 1. You will need to explicitly group the assignment:

(n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0

like how it's done in the Rio_readlineb_w function.

Assignment has lower precedence than most other operators, so be careful when using an assignment expression in a larger expression. For example,

a = b && c;

assigns the result of b && c to a. If you want to assign the result of b to a and compare that to c, then you'll need to use parentheses to indicate that:

(a = b) && c

Upvotes: 0

Mats
Mats

Reputation: 8638

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){
  printf("%d\n", n);
  Rio_writen_w(serverfd, buf, n);
}

Is the same as:

while (n = /* assignment has low priority */
          (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0)
       ) {
  printf("%d\n", n);
  Rio_writen_w(serverfd, buf, n);
}

I suspect you want:

while ((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0) {
  printf("%d\n", n);
  Rio_writen_w(serverfd, buf, n);
}

Upvotes: 1

interjay
interjay

Reputation: 110108

It's an issue of operator precedence.

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){

should be:

while((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0){

Otherwise, you're assigning the result of the comparison (0 or 1) to n.

Upvotes: 9

Related Questions