title: Why does it say "expression is not assignable"?
body: <p>Before I start, I just wanna clarify, that I know what the error means, I just don't know why it happened. Not only this is from the famous book but I'm not sure why pointer = pointer is illegal here. Anyway, here's the code from K&amp;R with some slight changes on the order of declarations and stuff, but mostly intact:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  #define MAXLINES 5000     /* max #lines to be sorted */
  #define MAXLEN 1000  /* max length of any input line */
  
  extern char *alloc(int);
  int igetline(char *, int);
  char *lineptr[MAXLINES];  /* pointers to text lines */
  int readlines(char *lineptr[], int nlines);
  void writelines(char *lineptr[], int nlines);
  void qsort(char *lineptr[], int left, int right);
  
  /* sort input lines */
  int main(void)
  {
      int nlines;     /* number of input lines read */
  
      if ((nlines = readlines(lineptr, MAXLINES)) &gt;= 0) {
          qsort(lineptr, 0, nlines-1);
          writelines(lineptr, nlines);
          return 0;
      } else {
          printf("error: input too big to sort\n");
          return 1;
      }
  }
  
  /* readlines: read input lines */
  int readlines(char *lineptr[], int maxlines)
  {
      int len, nlines;
      char *p, line[MAXLEN];
  
      nlines = 0;
      while ((len = igetline(line, MAXLEN)) &gt; 0)
          if (nlines &gt;= maxlines || p = alloc(len) == NULL)
              return -1;
          else {
              line[len-1] = '\0';  /* delete newline */
              strcpy(p, line);
              lineptr[nlines++] = p;
          }
      return nlines;
  }
  
  /* writelines: write output lines */
  void writelines(char *lineptr[], int nlines)
  {
      int i;
  
      for (i = 0; i &lt; nlines; i++)
          printf("%s\n", lineptr[i]);
  }
  
  /* igetline: read a line into s, return length */
  int igetline(char s[], int lim)
  {
      int c, i;
  
      for (i=0; i &lt; lim-1 &amp;&amp; (c=getchar())!=EOF &amp;&amp; c!='\n'; ++i)
          s[i] = c;
      if (c == '\n') {
          s[i] = c;
          ++i;
      }
      s[i] = '\0';
      return i;
  }
  
  /* qsort: sort v[left]...v[right] into increasing order */
  void qsort(char *v[], int left, int right)
  {
      int i, last;
      void swap(char *v[], int i, int j);
  
      if (left &gt;= right)  /* do nothing if array contains */
          return;         /* fewer than two elements */
      swap(v, left, (left + right)/2);
      last = left;
      for (i = left+1; i &lt;= right; i++)
          if (strcmp(v[i], v[left]) &lt; 0)
              swap(v, ++last, i);
      swap(v, left, last);
      qsort(v, left, last-1);
      qsort(v, last+1, right);
  }
  
  /* swap: interchange v[i] and v[j] */
  void swap(char *v[], int i, int j)
  {
      char *temp;
  
      temp = v[j];
      v[i] = v[j];
      v[j] = temp;
  }
  </code></pre>
  
  <p>Please note that alloc() is in another file. I don't think it has anything to do with this, but here's the code anyway:</p>
  
  <pre><code>#define ALLOCSIZE 10000 /* size of available space */
  
  static char allocbuf[ALLOCSIZE]; /* storage for alloc */
  static char *allocp = allocbuf;  /* next free position */
  
  char *alloc(int n) /* return pointer to n characters */
  {
      if (allocbuf + ALLOCSIZE - allocp &gt;= n) {
          allocp += n;
          return allocp - n;
      } else
          return 0;
  }
  
  void afree(char *p)   /* free storage pointed to by p */
  {
      if (p &gt;= allocbuf &amp;&amp; p &lt; allocbuf + ALLOCSIZE)
          allocp = p;
  }
  </code></pre>
  
  <p>When I tried to compile the code above, it gave me this error:</p>
  
  <pre><code>cc sample5.6.c alloc.c
  sample5.6.c:37:31: error: expression is not assignable
                  if (nlines &gt;= maxlines || p = alloc(len) == NULL)
                      ~~~~~~~~~~~~~~~~~~~~~~~ ^
  1 error generated.
  </code></pre>