This:
bit_is_set(optos(),opt)
expanding macro bit_is_set:
((*(volatile uint8_t *)(((uint16_t) &(optos())))) & (1 << (opt)))
is not working, with error message: lvalue required as unary '&' operand.
But this:
uint8_t a=optos();
bit_is_set(a,opt)
works fine.
Why?
How do I use the address operator "&" with function returns?
For the same reason why this won't work:
uint8_t optos() {
return 4;
}
int main(void) {
uint8_t* addr = &optos();
return 0;
}
error: lvalue required as unary ‘&’ operand
The & operand requires an lvalue to return an address. A temporary rvalue (in your case the value returned from optos()) can't have its address taken and needs to be bound to a lvalue first.
Related
why im getting errors in the code given below....
#include <stdio.h>
void foo(int*);
int main()
{
int i = 10;
foo((&i)++);(in this line error shows like this) //error: lvalue required as increment operand
}
void foo(int *p)
{
printf("%d\n", *p);
}
From Member access operators:
The address-of operator produces the non-lvalue address of its operand, suitable for initializing a pointer to the type of the operand.
And from Increment/decrement operators:
The operand expr of both prefix and postfix increment or decrement must be a modifiable lvalue of integer type (including _Bool and enums), real floating type, or a pointer type.
Simply put the & operator does not produce an appropriate object for the ++ operator.
I tryed to compile old code with new compiler and got the next error:
error: cannot take the address of an rvalue of type 'int'
Here is the example with 2 lines - one that compiles and the other that gives an error
struct mstct {
int myfield;
int myfield2[5];
int myfield3[5];
};
typedef struct mstct db_data_px;
int foo(int a, int b, int c){
//the next code compiles successfully.
unsigned val1 = ((18 == c) ? ((unsigned) & (((db_data_px *) 0)->myfield)) : ((unsigned) & (((db_data_px *) 0)->myfield3[b]))); //successes
//the next code is failing
unsigned val2 = (unsigned) & ((18 == c) ? (((db_data_px *) 0)->myfield) : (((db_data_px *) 0)->myfield3[b]));
return 0; // failing
}
Why the first line compiles and the second is failing ? Why do I need to cast (unsigned) & in both of the select expression and it is not enough to cast only after the select expression is valued ?
In your code
((18 == c) ? (((db_data_px *) 0)->myfield) : (((db_data_px *) 0)->myfield3[b]))
is a conditional expression which does not produce a lvalue.
The above expression gives you an rvalue (non-lvaue) and you cannot use & operator on that.
To elaborate, quoting C11 standard, chapter §6.5.3.2, Address and indirection operators
The operand of the unary & operator shall be either a function designator, the result of a
[] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier.
OTOH, for the result type of the conditional operator, chapter §6.5.15, footnote
A conditional expression does not yield an lvalue.
Just imagine, &5, not possible.
I have a question about lvalue and rvalue:
void * p;
typedef struct
{
int a;
int b;
} TypeA;
&(TypeA*)p; // here it complains lvalue required as unary '&' operand
why the (TypeA*)p gives a rvaule?
p is an object of type "pointer to void"; if you cast the value in p to type "pointer to TypeA" you no longer have an 'object': you have just a 'value'.
'Values' (like 42) have no address.
/* wrong code; this does not work */
int *p = &42; /* values do not */
void *q = &(0xDEADBEEF); /* have addresses */
Casting returns r-value and unary & needs a l-value as its operand.
Address-of Operator: &
The operand of the address-of operator can be either a function designator or an l-value that designates an object that is not a bit field and is not declared with the register storage-class specifier.
(TypeA*)p
This statement is going to type cast and return a value that needs to be assigned to a variable. so you can not directly use & on it since the return is a value which will not have a adress.
I have a code error but not sure what's wrong with my casting and reference.
BOOL xMBPortSerialPutByte( CHAR ucByte )
{
CDC_Send_DATA(&((unsigned char)ucByte), 1); // code error here
xMBPortEventPost(EV_FRAME_SENT);
return TRUE;
}
The CDC_Send_DATA is defined as the following:
uint32_t CDC_Send_DATA (uint8_t *ptrBuffer, uint8_t Send_length);
Here is the error message:
port/portserial.c:139:19: error: lvalue required as unary '&' operand
Hope someone could help. Thanks!
The cast operation causes a conversion, yielding an rvalue. An rvalue doesn't have an address, so you can't operate on it with a unary &. You need to take the address and then cast that:
CDC_Send_DATA((unsigned char *)&ucByte, 1);
But to be most correct, you should probably match the argument type in the cast:
CDC_Send_DATA((uint8_t *)&ucByte, 1);
Checking the return value would probably be a good idea too.
In the following code:
/* mylog.c */
#include <stdio.h>
#include <stdlib.h> /* for atoi(3) */
int mylog10(int n)
{
int log = 0;
while (n > 0)
{
log++;
n /= 10;
}
return log;
}
int mylog2(int n)
{
int log = 0;
while (n > 0)
{
log++;
n >>= 1;
}
return log;
}
int main(int argc, const char* argv[])
{
int (*logfunc)(int); /* function pointer */
int n = 0, log;
if (argc > 1)
{
n = atoi(argv[1]);
}
logfunc = &mylog10; /* is unary '&' operator needed? */
log = logfunc(n);
printf("%d\n", log);
return 0;
}
in the line
logfunc = &mylog10;
I've noticed that the unary & (address of) operator is optional, and the program compiles and runs the same way either with or without it (in Linux with GCC 4.2.4). Why? Is this a compiler-specific issue, or perhaps two different language standards being accepted by the compiler? Thanks.
You are correct that the & is optional. Functions, like arrays, can be automatically converted into pointers. It's neither compiler-specific nor the result of different language standards. From the standard, Section 6.3.2.1, paragraph 4:
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator or the unary & operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
Operator & is indeed optional when taking the address of a function in your context (assigning it to something). It is not compiler-specific, it follows from the formal definition of the language.
Symmetrically, operator * is optional when invoking the function through a pointer. In your example, you could invoke the function as either (*logfunc)(n) or logfunc(n). You used the latter, but the former would work as well.
Answering in C++. For C the same holds
Quote from the C++ standard (4.3.1):
An lvalue of function type T can be
converted to an rvalue of type
“pointer to T.” The result is a
pointer to the function.50)
The same for arrays. (4.2.1)
An lvalue or rvalue of type “array ofN
T” or “array of unknown bound of T”
can be converted to an rvalue of type
“pointer to T.” The result is a
pointer to the first element of the
array.
But please DO note that these are conversions and by no means is a function a function-pointer or is an array a pointer. HTH
From the standard (6.3.2.1/4) :
A function designator is an expression
that has function type. Except when it
is the operand of the sizeof
operator or the unary & operator, a
function designator with type
‘‘function returning type’’ is
converted to an expression that has
type ‘‘pointer to function returning
type’’.
So yes, omitting the & yields a pointer to function anyway.