I've got an error that I can't find in any library:
In function
'void__vector_2()'
error lvalue required as left operand of assigment.
Related
Is there any way of determining whether a given expression is an lvalue or an rvalue in C? For instance, does there exist a function or macro is_lvalue with the following sort of behaviour:
int four() {
return 4;
}
int a = 4;
/* Returns true */
is_lvalue(a);
/* Returns false */
is_lvalue(four());
I know equivalent functionality exists in C++, but is there any way of doing this in any standard of C? I'm not particularly interested in GCC-specific extensions.
Thank you for your time.
The C standard does not provide any method for detecting whether an expression is an lvalue or not, either by causing some operation to have different values depending on whether an operand is an lvalue or not or by generating a translation-time diagnostic message or error depending on whether an operand is an lvalue or not.
C implementations may of course define an extension that provides this feature.
About the closest one can get in strictly conforming C is to attempt to take the address of the expression with the address-of operator &. This will produce a diagnostic message (and, in typical C implementations, an error) if its operand is not an lvalue. However, it will also produce a message for lvalues that are bit-fields or that were declared with register. If these are excluded from the cases of interest, then it may serve to distinguish between lvalues and non-lvalues during program translation.
This question already has answers here:
1998 vintage C code now fails to compile under gcc
(2 answers)
Closed 2 years ago.
This line-palindromic entry from the 1987 IOCCC:
https://www.ioccc.org/years.html#1987_westley
...is causing TCC 0.9.27 no issues during default compilation and works as intended.
However, GCC 9.3.0, even in -std=c89 mode, complains that the following instances of (int) (tni) are not lvalues:
for (; (int) (tni);)
(int) (tni) = reviled;
^
(lvalue required as left operand of assignment)
...
for ((int) (tni)++, ++reviled; reviled * *deliver; deliver++, ++(int) (tni))
^~
(lvalue required as increment operand)
(code beautified for better context)
My current thoughts:
In the = case, I suspect that the use of (int) (tni) as a condition in the for loop is disqualifying it as a lvalue, but I am not sure.
In the ++ case, I can see later in that code how its palindromic nature forces the author to use a -- operator between (int) and (tni) which is not considered as an issue. So GCC requires the ++ operator just before the variable, not before its casting, but hints at this requirement with a lvalue complaint.
Is there a definitive answer to these GCC complaints? Is TCC too lax in letting these off the hook?
Thanks in advance!
EDIT: I was kindly pointed towards a similar question which answers the casting issue here - please see my comment below for the solution!
TCC is not a conforming C implementation as is well known - TCC tries to be small and fast compiler that attempts to compile correct C code, and it often does not produce diagnostics that would be required by the standard. And as is known even more widely is that the first C standard came into being in 1989, and most widely known is that year 1987 preceded 1989.
C11 6.5.4p5:
Preceding an expression by a parenthesized type name converts the value of the expression to the named type. This construction is called a cast. 104) A cast that specifies no conversion has no effect on the type or value of an expression.
The footnote 104 notes that:
A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the unqualified version of the type.
For assignment operator, 6.5.16p2 says:
An assignment operator shall have a modifiable lvalue as its left operand.
6.5.16p2 is in constraint section, so violations must be diagnosed.
I am new to MISRA rules concepts. I have a rule 12.2 warning saying
The value of an expression shall be the same under any order of
evaluation that the standard permits (MISRA C 2004)
on the following C code:
PtToStack->Entry[PtToStack->top] = e ;
where PtToStack is pointer to stack, Entry is array in the stack structure and top variable is a field of the stack structure.
e has the same type of Entry.
Could any one help me to understand the warning?
This rule from MISRA-C:2004 (older standard) is concerning the order of evaluation of operands, in expressions where the order is not specified. There are plenty of examples and education material regarding the issue, below rule 12.2.
In your expression, there are no issues with unspecified order of evaluation. Therefore, the warning is incorrectly generated by your tool. Your static analyser is bad, file a bug report with the tool vendor.
I don't usually require assistance understanding error messages, however this one seems like it must be a bug. I've combed through the "questions that may already have your answer", but none of those appear to be using the recent _Generic feature added by C11, so I think this might be a unique issue. Here is my testcase:
#include <stdio.h>
#define foo(bar) _Generic((bar), int: sizeof (bar) \
, int *: sizeof *(bar))
int main(void) {
printf("%d\n", foo(42));
}
The error message I'm seeing for gcc 5.2 reads:
error: invalid type argument of unary '*' (have 'int')
note: in expansion of macro 'foo'
clang emits a message of similar meaning:
fatal error: indirection requires pointer operand ('int' invalid)
note: expanded from macro 'foo'
These messages seem to imply one of the following:
The compiler chose the expression from the int * generic association.
The expressions from the generic associations were both evaluated.
C11ยง6.5.1.1p3 seems to forbid both of these explanations explicitly:
The controlling expression of a generic selection is not evaluated. If a generic selection has a generic association with a type name that is compatible with the type of the controlling expression, then the result expression of the generic selection is the expression in that generic association. Otherwise, the result expression of the generic selection is the expression in the default generic association. None of the expressions from any other generic association of the generic selection is evaluated.
Can anybody shed some light on this error message for me?
The compiler is right: sizeof *(42) is a constraint violation because it applies the * to an expression of integer type. Now one thing for _Generic is important to know, this is not processed a preprocessing time but as a proper expression in the sense of the C language (with the highest precedence). The effects of this _Generic expression actually the same as doing something like
(1 ? sizeof (42) : sizeof *(42))
Here you know that the second branch is never evaluated, still nobody expects this to compile.
My CCS 6.1 ARM compiler (for LM3Sxxxx Stellaris) throws a warning:
"MISRA Rule 10.1. The value of an expression of integer type shall not be implicitly converted to a different underlying type if the expression is
not constant and is a function argument"
for following code:
static uint32_t diagBaseAddress;
void diagCbGetBaseAddress(uint32_t * addr);
...
diagCbGetBaseAddress(&diagBaseAddress); // line where warning is issued
...
I don't see a problem in my code. Is it false positive or my bug?
Yes, it is a false positive. Rule 10.1 of MISRA-C:2004 is concerned about implicit type promotions of integer types. Pointers have nothing to do with that rule.
Though make sure that none of the adjacent code lines contain the actual problem, the tool could simply be pointing at the wrong line.
(I can tell it is the 2004 version because it mentions underlying type. In the 2012 version, the concept of underlying type was replaced.)