error: lvalue required as left operand of assignment

I get the following error:

pointers_array.c: In function ‘readlines’:
pointers_array.c:42:37: error: lvalue required as left operand of assignment


I know what the error is saying but I have no idea what it is giving it with this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* readlines: read input lines */
int readlines(char *lineptr[], int maxlines)
{
    int len, nlines;
    char *p, line[MAXLEN];
    nlines = 0;

    while ((len = my_getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || p = my_alloc(len) == NULL)
           return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            my_strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}



Here's the whole context:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdio.h>
#include <string.h>

#define MAXLINES 5000   /* max #lines to be sorted */
#define MAXLEN 1000     /* max length of any input line */
#define ALLOCSIZE 10000 /* size of available space */

char *lineptr[MAXLINES];          /* pointers to text lines */
static char allocbuf[ALLOCSIZE];  /* storage for alloc */
static char *allocp = allocbuf;   /* next free position */

int  my_getline(char *, int);
char *my_alloc(int);
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void my_strcpy(char *s, char *t);
void my_qsort(char *v[], int left, int right);
void my_swap(char *v[], int i, int j);

/* sort input lines */
main()
{
    int nlines;		/* number of input lines read */
    if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
        my_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 = my_getline(line, MAXLEN)) > 0)
        if (nlines >= maxlines || p = my_alloc(len) == NULL)
           return -1;
        else {
            line[len-1] = '\0'; /* delete newline */
            my_strcpy(p, line);
            lineptr[nlines++] = p;
        }
    return nlines;
}

/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
    int i;

    for (i = 0; i < nlines; i++)
        printf("%s\n", lineptr[i]);
}

/* getline: get line into s, return length */
int my_getline(char *s, int lim)
{
    char *p;
    int c;

    p = s;
    while (--lim > 0 && (c = getchar()) != EOF && c != '\n')
        *p++ = c;
    if (c == '\n')
        *p++ = c;
    *p = '\0';
    return (int)(p - s);
}

char *my_alloc(int n)	/* return pointer to n characters */
{
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else	/* not enough room */
        return 0;
}
 
void my_strcpy(char *s, char *t) { 
    while (*s++ = *t++) 
        ; 
}

/* qsort: sort v[left]...v[right] into increasing order */ 
void my_qsort(char *v[], int left, int right) 
{ 
	int i, last; 
	
	if (left >= right)  /* do nothing if array contains */ 
		return;			/* fewer than two elements */
		
	my_swap(v, left, (left + right)/2);
	last = left;						
	for (i = left+1; i <= right; i++) 
		if (strcmp(v[i], v[left]) < 0) 
			my_swap(v, ++last, i); 
			
	my_swap(v, left, last); 
	my_qsort(v, left, last-1);
	my_qsort(v, last+1, right);
}

/* swap: interchange v[i] and v[j] */ 
void my_swap(char *v[], int i, int j) 
{ 
	char *temp; 
	
	temp = v[i]; 
	v[i] = v[j]; 
	v[j] = temp;
}
Operator precedence.

if (nlines >= maxlines || p = my_alloc(len) == NULL)
is the same as
if ( (nlines >= maxlines || p) = (my_alloc(len) == NULL) ).
Are you sure about that?

The comparison operators have higher precedence than the logical operators, with assignment with the lowest precedence. So I see it as follows:

comparison first:
if ( (nlines >= maxlines) || p = (my_alloc(len) == NULL) )

logical second:
if ( ((nlines >= maxlines)) || (p = (my_alloc(len) == NULL)) )
Maybe I made a mistake somewhere.

Hang on a sec.
Let's try this again:

if (nlines >= maxlines || p = my_alloc(len) == NULL)
is the same as
if ( (nlines >= maxlines) || p = my_alloc(len) == NULL)
which is the same as
if ( (nlines >= maxlines) || p = (my_alloc(len) == NULL) )
which is the same as
if ( ( (nlines >= maxlines) || p) = (my_alloc(len) == NULL) ).

http://en.cppreference.com/w/cpp/language/operator_precedence

So yeah, the || binds tighter than the =, so I didn't make a mistake anywhere.

In general, when in doubt, use parentheses!
They never hurt, and you can't go wrong with them! (Well, unless you mess up your parentheses, but that's another matter....)
Last edited on
Topic archived. No new replies allowed.