Address of dereferenced pointer construct - c

In unqlite c library I found following code:
pObj = jx9VmReserveMemObj(&(*pVm),&nIdx);
where pVm is:
typedef struct jx9_vm jx9_vm;
jx9_vm *pVm
and function called is declared as:
jx9_value * jx9VmReserveMemObj(jx9_vm *, sxu32 *);
What for construct &(*pVm) is used in call instead of just pVm? Is &(*pVm) equivalent to pVm?

Quoting C11, chapter §6.5.3.2, Address and indirection operators
[...] If the operand is the result of a unary * operator,
neither that operator nor the & operator is evaluated and the result is as if both were
omitted, except that the constraints on the operators still apply and the result is not an lvalue. [...]
So, yes, they are equivalent.
This construct can be used, however, to check the type of the argument against a pointer type. From the property of unary * operator,
The operand of the unary * operator shall have pointer type.
So, the construct &(*pVm)
will be fine, if pvm is a pointer or array name.
will generate compiler error, if pvm is a non-pointer type variable.
See the other answer by Alter Mann for code-wise example.
One more difference (in general) is, pVm can be assigned (can be used as LHS of the assignment operator), but &(*pVm) cannot.

Is &(*pVm) equivalent to pVm?
Yes. *1
Same for *(&pVm).
(*1)
As the *-operator (de-referencing) only is applicable to pointers, the former construct only works on a pointer (or an array, which would decay to a pointer to its 1st element). The latter can be applied to any type of variable.:

Yes, they are the same, but notice that it fails when the object is not an array or a pointer:
#include <stdio.h>
struct t {
int value;
};
typedef struct t t;
int func(t *ptr)
{
return ptr->value;
}
int main(void)
{
t o = {.value = 0};
t v[2] = {{.value = 1}, {.value = 2}};
printf("%d\n", func(&(*o))); /* error: invalid type argument of unary ‘*’ */
printf("%d\n", func(&(*v))); /* WORKS */
return 0;
}

Related

Instead of using sizeof(type), use sizeof *p,is it safe and correct?

Is this safe to use,This code compiled with gcc 4.9.2 without any error or warning
widget *p;
...
p = malloc(sizeof *p);
I found this on SEI CERT C Coding Standard website.
Click here
-- no type mismatch issues, no need for casting. You allocate the right amount of memory every time.
struct widget;
typedef struct widget widget_t;
struct gadget;
typedef struct gadget gadget_t;
widget_t *newWidget(void)
{
widget_t *p = malloc(sizeof *p);
if (p)
/* initialize members of *p as necessary */
return p;
}
gadget_t *newGadget(void)
{
gadget_t *p = malloc(sizeof *p);
if (p)
/* initialize members of *p as necessary */
return p;
}
void deleteWidget(widget_t **p)
{
/* delete any subelements of *p */
free(*p);
*p = NULL;
}
void deleteGadget(gadget_t **p)
{
/* delete any subelements of *p */
free(*p);
*p = NULL;
}
...
widget_t *p = newWidget();
gadget_t *g = newGadget();
if (p)
/* do stuff with p */
if (g)
/* do stuff with g */
...
deleteWidget(&p);
deleteGadget(&g);
The sizeof operator has the following definition
sizeof unary-expression
sizeof ( type-name )
Thus in this declaration
widget_t *p = malloc(sizeof *p);
there is used the first form of the operator where the expression *p is an unary expression and has the type of widget_t.
Thus these declarations
widget_t *p = malloc(sizeof *p);
widget_t *p = malloc(sizeof( widget_t ) );
are totally equivalent.
The first declaration is preferable because the expression in the sizeof operator does not depend on the actual type. That is the type of the pointer can be changed but the declaration will be valid without any other changes.
In C there is no need to cast the pointer returned from malloc to the type of the assigned lvalue because a pointer of the type void * may be assigned to pointer to object of any type. It is sometimes used (and moreover sometimes useful) to make the program self-documented.
It's a good coding practice!
Imagine this code
struct structv1 *p1 = malloc(sizeof (struct structv1));
struct structv1 *p2 = malloc(sizeof *p2);
gets changed to
struct structv2 *p1 = malloc(sizeof (struct structv2));
// ^^^^^^^^ ^^^^^^^^^^^^^^^^^
// two changes! maybe the programmer forgets one of them
struct structv2 *p2 = malloc(sizeof *p2);
// ^^^^^^^^
// one change only. the argument to malloc is already correct
Short answer: yes, it's safe.
sizeof isn't a function; it's an operator. Used as you've shown, it returns the size in bytes of the object representation of the type of the expression. The expression itself isn't evaluated at run-time; it instead feeds a type to the sizeof operator at compile time, and thus no harm or foul.
Using sizeof *p instead of sizeof (type) is safe with one exception - if p is an uninitialized or invalid pointer to a variable-length array, then the behavior is undefined. For example:
size_t rows, cols;
...
T (*p)[cols] = malloc( rows * sizeof *p ); // *p is undefined here
For every type except variably-modified types, the operand of sizeof is not evaluated. For variable-length arrays, it is evaluated, and since p is invalid until after the malloc call completes, applying the * operator to it results in undefined behavior.
Chapter and verse
6.5.3.2 Address and indirection operators
...
4 The unary * operator denotes indirection. If the operand points to a function, the result is
a function designator; if it points to an object, the result is an lvalue designating the
object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
invalid value has been assigned to the pointer, the behavior of the unary * operator is
undefined.102)
...
6.5.3.4 The sizeof and _Alignof operators
...
2 The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. The size is determined from the type of
the operand. The result is an integer. If the type of the operand is a variable length array
type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.
102) ...
Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an
address inappropriately aligned for the type of object pointed to, and the address of an object after the
end of its lifetime.
Now, I've used the above code a number of times and have never had any issues, but that's not a guarantee of anything - I've only ever used it on one particular architecture (x68) and with a limited range of compilers. There's no guarantee that it won't blow up spectacularly on some oddball architecture.
It's an incredibly useful idiom, though, and I kind of wish the standard were worded better to properly define it. I don't have a copy of the very latest (2011 is the most recent I have access to), so I don't know if they've tweaked that language any.

Can the pointer dereferencing sign * be called "many"?

I saw that pointer to either a single variable or an array in C is declared and printed using the same syntax. So I thought of * to be called many like in regular expression sign * which means many such as x*=xxx....
int a[3] = { 4, 5, 6 };
int b = 3;
int *p, *q; // same syntax for either single variable or array
p = a; // pointer to many int
q = &b; // pointer to an int
printf("%d %d", *p, *q); // same syntax again
So can I call both p and q as pointer to many int for ease of understanding?
No, that's not a good idea. A pointer can only point to a single variable, although that is often the first element of an array. p = a; is the pointer to the first element in the array a, and only to that one. The pointer in itself can't know if there's more valid data following the address it is currently pointing at.
For example, it's not meaningful to write a function like void print_array(int* p) since that function won't know the size of the array, since p only points at the first element. We would rather write something like void print_array(int* p, int size)
Advanced topic (ignore if beginner): A pointer to "many int" would rather be the more exotic feature called "array pointer", such as int (*)[3] = &a;. You can think of this as "a pointer to the whole array" rather than just to the first element.
Well, not really, the types are not interchangeable.
While used as the RHS of assignment (among many other cases), a variable with type array decays to the type of pointer to the first element of the array.note
So,
p = a;
is the same as
p = &(a[0]);
where both the sides are of type pointer to integer (int *).
NOTE:
Quoting C11, chapter §6.3.2.1
Except when it is the operand of the sizeof operator, the _Alignof operator, or the
unary & operator, or is a string literal used to initialize an array, an expression that has
type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points
to the initial element of the array object and is not an lvalue. [...]

what pointer magic is this

I am learning C. I am starting to understand pointers and type casting. I am following along with some guides and examples and I ran across this declaration:
uint32_t *sp;
...
*(uint32_t*)sp = (uint32_t)somevalue;
What is happening here? The first asterisk specifically is a mystery to me.
Breaking it down:
*(uint32_t*)sp
basically says to treat sp as a pointer to uint32_t ((uint32_t *) is a cast expression), and to dereference the result.
So,
*(uint32_t*)sp = (uint32_t)somevalue;
means, "take somevalue, convert it to type uint32_t, and store the result to the thing sp points to, and treat that thing as though it were also a uint32_t."
Note that the cast on sp is redundant; you've already declared it as a pointer to uint32_t, so that assignment could be written as
*sp = (uint32_t) somevalue;
The first asterisk dereferences the sp pointer in order to assign the value of somevalue to the pointee.
I wonder why the cast, since this
*sp = (uint32_t) somevalue;
if sp is of type uint32_t * is fine.
The first star dereferences sp after it had been cast to a pointer to a uint32_t, so that somevalue is written to that location.
However, the cast is unnecessary since sp is already a pointer to a uint32_t. Furthermore, if somevalue is a numeric type, the cast on the right hand side is unnecessary too since the rvalue will be implicitly cast to the type of the lvalue.
The first asterisk is the indirection operator.
It is basically to get/access the value at the address held by the pointer.
Quoting the C11 standard, chapter §6.5.3.2, Address and indirection operators
The operand of the unary * operator shall have pointer type.
and
The unary * operator denotes indirection. If the operand points to a function, the result is
a function designator; if it points to an object, the result is an lvalue designating the
object. [...]
Your confusion stems from the fact that this is not a declaration but in fact an assignment statement:
/* This is the declaration of sp as a pointer to uint32_t */
uint32_t *sp;
/* This is an assignment statement setting *sp to somevalue */
*(uint32_t*)sp = (uint32_t) somevalue;
It looks confusingly like a declaration because of the unnecessary casting of the lvalue which makes it sort of look like it's declaring the type.

Why the cast give a rvalue in C?

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.

C pass address of a function return value as function parameter

I have two functions:
void a(int * p);
int b();
Is it possible to pass the address of the return value of function b to function a something like this: a(&b()) ?
A compound literal seems to do the trick (requires a C99 compiler):
int a()
{
return 5;
}
void b(int *a)
{
// do something with a
printf("%d\n", *a);
}
int main(void)
{
b(&(int){ a() });
}
Output is 5.
Only by using a temporary variable:
int result = b();
a(&result);
EDIT: Apparently there's also a way to do this using a compound literal, described in another answer here.
Nope - what would be the address of that return value? You need to store the return value in a variable, then pass the address of that variable in.
No. C11 says that (emphasis mine):
6.5.3.2.1
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.
Now it clearly isn't a function, a [] or a unary *. Let's see what is an lvalue:
6.3.2.1
An lvalue is an expression (with an object type other than void) that potentially
designates an object;64) if an lvalue does not designate an object when it is evaluated, the
behavior is undefined. ...
64) The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left
operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an
object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described
as the ‘‘value of an expression’’.
An obvious example of an lvalue is an identifier of an object. As a further example, if E is a unary
expression that is a pointer to an object, *E is an lvalue that designates the object to which E points.
So in short, an lvalue designates an object. Since b() doesn't designate a specific object, it is not an lvalue. You can tell this by seeing also that b() = 2; is wrong.
No you can't do that in C. Also note C doesn't have something called as reference as in C++.
For that C has pointers to achieve the same behaviour..
To achieve the same goal in C use temporary variable like,
int val;
val = b();
a( &val ); // & is called as "address of" operator in C
To answer why there is no reference in C, from my understanding pointer and reference are meant to achieve the same goal - minimizing or avoiding data copy. For this C's pointer is good enough, though technically both have some difference in C++ (taken for reference)
You could pass a reference to b() as an argument to a then call b from a:
void a(void (*b)(int)) {
// call b
int local_var = b(<something>);
}

Resources