PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label dereference. Show all posts
Showing posts with label dereference. Show all posts

Monday, December 12, 2022

[FIXED] What do the ampersand '&' and star '*' symbols mean in Rust?

 December 12, 2022     dereference, reference, rust, syntax     No comments   

Issue

Despite thoroughly reading the documentation, I'm rather confused about the meaning of the & and * symbol in Rust, and more generally about what is a Rust reference exactly.

In this example, it seems to be similar to a C++ reference (that is, an address that is automatically dereferenced when used):

fn main() {
    let c: i32 = 5;
    let rc = &c;
    let next = rc + 1;
    println!("{}", next); // 6
}

However, the following code works exactly the same:

fn main() {
    let c: i32 = 5;
    let rc = &c;
    let next = *rc + 1;
    println!("{}", next); // 6
}

Using * to dereference a reference wouldn't be correct in C++. So I'd like to understand why this is correct in Rust.

My understanding so far, is that, inserting * in front of a Rust reference dereferences it, but the * is implicitly inserted anyway so you don't need to add it (while in C++, it's implicitly inserted and if you insert it you get a compilation error).

However, something like this doesn't compile:

fn main() {
    let mut c: i32 = 5;
    let mut next: i32 = 0;
    {
        let rc = &mut c;
        next = rc + 1;
    }
    println!("{}", next);
}
error[E0369]: binary operation `+` cannot be applied to type `&mut i32`
 --> src/main.rs:6:16
  |
6 |         next = rc + 1;
  |                ^^^^^^
  |
  = note: this is a reference to a type that `+` can be applied to; you need to dereference this variable once for this operation to work
  = note: an implementation of `std::ops::Add` might be missing for `&mut i32`

But this works:

fn main() {
    let mut c: i32 = 5;
    let mut next: i32 = 0;
    {
        let rc = &mut c;
        next = *rc + 1;
    }
    println!("{}", next);  // 6
}

It seems that implicit dereferencing (a la C++) is correct for immutable references, but not for mutable references. Why is this?


Solution

Using * to dereference a reference wouldn't be correct in C++. So I'd like to understand why this is correct in Rust.

A reference in C++ is not the same as a reference in Rust. Rust's references are much closer (in usage, not in semantics) to C++'s pointers. With respect to memory representation, Rust's references often are just a single pointer, while C++'s references are supposed to be alternative names of the same object (and thus have no memory representation).

The difference between C++ pointers and Rust references is that Rust's references are never NULL, never uninitialized and never dangling.


The Add trait is implemented (see the bottom of the doc page) for the following pairs and all other numeric primitives:

  • &i32 + i32
  • i32 + &i32
  • &i32 + &i32

This is just a convenience thing the std-lib developers implemented. The compiler can figure out that a &mut i32 can be used wherever a &i32 can be used, but that doesn't work (yet?) for generics, so the std-lib developers would need to also implement the Add traits for the following combinations (and those for all primitives):

  • &mut i32 + i32
  • i32 + &mut i32
  • &mut i32 + &mut i32
  • &mut i32 + &i32
  • &i32 + &mut i32

As you can see that can get quite out of hand. I'm sure that will go away in the future. Until then, note that it's rather rare to end up with a &mut i32 and trying to use it in a mathematical expression.



Answered By - oli_obk
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 10, 2022

[FIXED] How to simulate pointers in JavaScript?

 July 10, 2022     dereference, javascript, pointers, reference, simulation     No comments   

Issue

I am creating a language which is compilable to Swift, Rust, and JavaScript (or at least trying). Rust and Swift both use pointers/references/dereferencing/etc., while JavaScript does not. So in a Rust-like language, you might do something like this:

fn update(x) {
  *x++
}

fn main() {
  let i = 0
  update(&i)
  log(i) #=> 1
}

In a JavaScript-like language, if you did this then it would fail:

function update(x) {
  x++
}

function main() {
  let i = 0
  update(i)
  log(i) #=> 0
}

Because the value is cloned as it is passed in (as we obviously know).

So what I am thinking about is doing this at first:

function update(scopeWithI) {
  scopeWithI.i++
}

function main() {
  let i = 0
  let scopeWithI = { i }
  update(scopeWithI)
  i = scopeWithI.i
  log(i) #=> 1
}

But that is a lot of extra processing going on, and kind of unnecessary it seems. Instead I might try compiling to this:

function update(scopeWithI) {
  scopeWithI.i++
}

function main() {
  let scope = {}
  scope.i = 0
  update(scope)
  log(scope.i) #=> 1
}

This would mean every nested scope you create, you would have to start manually creating/managing the scope chain. And actually that wouldn't work because update is hardcoded to i. So you might have to pass in what the variable name is you want.

function update(scope, ...names) {
  scope[names[0]]++
}

But then it's like:

function update(scope, ...names) {
  scope[names[0]]++
}

function main() {
  let scope = {}
  scope.i = 0
  if random() > 0.5
    let childScope = { scope }
    childScope.x = 0
    update(childScope, ['i'])
    update(childScope, ['x'])
    update(childScope, ['x'])
    log(childScope.x) #=> 2
  else
    update(childScope, ['i'])

  log(scope.i) #=> 1
}

So that seems like it might get us somewhere.

So then it's like, the generic solution is to have scope be the first parameter to a function.

function add(scope, name1, name2) {
  return scope[name1] + scope[name2]
}

Dereferencing means reading a value directly from the scope, while passing a reference (like &name in Rust or C), would mean passing the scope and the name.

Will something like this work? Or better put, what needs to be changed or added? Does it need to get any more complicated than this?

I would like to try and find a way to transform the pointer-oriented code into JavaScript (transpilation), without at first trying to figure out the seemingly much more complicated approach of not being so direct, and avoiding pointer simulation in JavaScript by redefining a lot of the methods. It seems that avoiding any pointer use in JavaScript would be way harder to figure out, so I am trying to see if a pointer sort of system would be possible to simulate in JavaScript.

To avoid pointer simulation, you would have to redefine methods.

update(x) {
  *x++
}

Would have to change the outer usage of the function everywhere. So this:

main() {
  let i = 0
  update(&i)
}

Would become:

main() {
  let i = 0
  i++ // inline the thing
}

For this simple case it's fine, but for a more complicated function it starts to seem like macros and might get complicated.

So instead of changing the outer usage, we make it so you have to pass the scope.

Another approach might be to have every variable be an object with a value, so it's more like:

update(x) {
  x.value++
}

main() {
  let i = { value: 0 }
  update(i)
}

So then I'm thinking to myself, how to handle references to references then?

update2(x) {
  update(&x)
}

update(x) {
  *x++
}

main() {
  let i = 0
  update2(&i)
}

In the system i described, that would be like:

update2(x) {
  // then what?
  let y = { value: x }
  update(y)
}

update(x) {
  // like this?
  x.value.value++
}

main() {
  let i = { value: 0 }
  update2(i)
}

So it seems this wouldn't really work.


Solution

Needless to say, but JavaScript does not have a general mechanism to pass arguments by reference.

There can be some confusion around the term "reference", as in JavaScript one can pass objects to functions -- which are references -- but this is a call-by-value mechanism. Call-by-reference really means that the parameter variable is an alias for the caller's variable, such that assigning to that alias is equivalent to assigning to the caller's variable. Except for some very particular situations (like the arguments exotic object in non-strict mode, or the export mechanism, or the var link with the window object, none of which helps you in your case in a best practice way), there is no such variable-aliasing mechanism in JavaScript.

Here is an example on how to "exploit" the effect of var in a browser context, in non-strict mode:

function modify(ref) {
    // Using the fact that global `var` variables are aliases
    //  for properties on the global object
    // (This is not considered good practice)
    globalThis[ref] = globalThis[ref] + 1;
}

var a = 1;
modify("a"); // We pass a reference to `a`
console.log(a);

In short, apart from some bad design in the old JavaScript language (in sloppy mode), it just is not possible in JavaScript in general. All your attempts that work, perform a mutation on a given object, by setting one of its properties. You cannot hope to have a function that assigns to a parameter variable, thereby modifying the caller's variable. It just is not possible -- by design. Note the important distinction between assignment and mutation.

If the caller's variable (not a property) needs to be assigned a new value (not just mutation, but really assignment), then that assignment must happen to that variable -- something a function cannot do for the caller.

So the way to perform such an assignment in JavaScript, is that you make the function return whatever the caller needs to reassign, and it remains the responsibility of the caller to perform that assignment:

function modify(value) {
    return 3;
}

let value = 1;
value = modify(value);
console.log(value);

When you have more than one variable that is involved, let the function return a "packed" object, which the caller can destructure back into its own variables:

function modify(a, b) {
    return [a + 1, b * 2];
}

let a = 1, b = 2;
[a, b] = modify(a, b);
console.log(a, b);



Answered By - trincot
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] When to dereference or not

 July 10, 2022     dereference, pointers, reference, rust     No comments   

Issue

I am going through the "Rust Book" website in order to learn the language for an upcoming job interview. In the chapter on vectors, there are two code samples:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", i);
    }
}

and:

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}

Now I am wondering, why is it that for the first sample, when we pass the reference to the vector element i into:

println!("{}", i);

but in the sample where we add 50 to each element of the vector, we have to dereference the element with * before we add to the 50?

Why don't/can't we do the following:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", *i); // why don't we have to dereference before we pass to println!?
    }
}

or:

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        i += 50; // why can't we just add directly to the reference like this?
    }
}

I must have misunderstood what I read, but I thought Rust was able to discern when you need to dereference or not automatically. I guess I don't understand why we need to dereference (or not dereference) in the two samples. The two examples I provided are commented with the specific bits of code I am wondering about.


Solution

I think the easiest way to look at this is that the second example is the "normal" one.

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}

i is a &mut i32 (only i32 because there's nothing from which to infer any other integer type), so to assign to it you need to dereference to a mut i32.

The println! example is the one doing some "magic". println! will format types whether they're passed by value or by reference. This is very handy, you wouldn't want it to (for example) clone every string you want to print out but then use later in the application.


Edit:

For completeness, this "magic" isn't really magic at all, but nice use of language features. println! (like every other standard macro that does formatting, like panic! and format!) uses the formatting machinery from the standard library. This can work with any type that implements the Display trait (or the Debug trait if you use {:?}). And Display has a blanket impl for all references of things the implement Display (Debug also does this):

impl<'_, T> Display for &'_ T where
    T: Display + ?Sized, 
{ /* ... */ }

So anything you can format with a value, you can also format with a reference.



Answered By - JMAA
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 6, 2022

[FIXED] How to visualize the pointers in the code snippet?

 July 06, 2022     c, dereference, gcc, pass-by-reference, pointers     No comments   

Issue

I am finding it difficult to visualize this piece of code. I cannot seem to find the ans to this.

I did get the ans for

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

but other variables are not matching the ans. Please help.

int f(int ** r, int ** s) {
    int temp = ** r;
    int temp2 = **s;
    int * z = *r;
    *r = *s;
    *s = z;

    printf("**r = %d\n",**r);
    printf("**s = %d\n",**s);
    *z += 3;
    **s -= 8;
    **r -= 19;

    return temp + temp2;
}

int main(void) {
    int a = 80;
    int b = 12;
    int * p = &a;
    int * q = &b;
    int x = f(&p, &q);

    printf("x = %d\n", x);
    printf("*p = %d\n", *p);
    printf("*q = %d\n", *q);
    printf("a = %d\n", a);
    printf("b = %d\n", b);

    return EXIT_SUCCESS;
}

Expected output:

**r = 12
**s=80
x=92
*p=-7
*q=75
a=75
b=-7 

Solution

In this declaration the pointers p and q are passed by reference to the function f.

int x = f(&p, &q);

The pointer p points to the variable a and the pointer q points to the variable b.

int a = 80;
int b = 12;
int * p = &a;
int * q = &b;

Within the function f declared like

int f(int ** r, int ** s);

the pointer r points to the pointer p and the pointer s points to the pointer q.

Correspondingly in these declarations

int temp = ** r;
int temp2 = **s;

the variable temp is initialized by the value of variable a and the variable temp2 is initialized by the value of the variable b.

You van imaging these declaration like

int temp = a;
int temp2 = b;

In this code snippet

int * z = *r;
*r = *s;
*s = z;

there are in fact swapped the the pointers p and q pointed to by the pointers r and s. That is after this code snippet the pointer r now points to the pointer q and the pointer s points to the pointer p.

You can imaging this like

*r = q;
*s = p;

The intermediate variable z

int * z = *r;

gets the value of the pointer p.

You can imaging this like

int * z = p;

This statement

*s = z;

did not change the value pointed to by s because before this statement the variable s already pointed to p due to preceding swapping the pointed values of the pointer r and the pointer s.

So these calls of printf

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

correspondingly will output the value of b and the value of a.

That is the output will be

**r = 12
**s = 80

As the pointer z has the value of the pointer p then after this statement

*z += 3;

the variable a will be increased by 3 and becomes equal to 83.

In these statements

**s -= 8;
**r -= 19;

the variable a will be decrease by 8 and becomes equal to 75 And the variable b is decreased by 19 and becomes equal to -7.

At last the function returns the sum of the initial values of the variables a and b

return temp + temp2;

that is 92.

In these statements in main

printf("x = %d\n", x);
printf("*p = %d\n", *p);
printf("*q = %d\n", *q);
printf("a = %d\n", a);
printf("b = %d\n", b);

there is outputted the value returned by the function f

printf("x = %d\n", x);

that is 92.

As the pointers p and q were swapped in the function then now the pointer p points to b and the pointer q points to a.

printf("*p = %d\n", *p);
printf("*q = %d\n", *q);

So these statements output

*p = -7
*q = 75

And these statements

printf("a = %d\n", a);
printf("b = %d\n", b);

outputs the new values of a and b themselves that is

a = 75
b = -7

As for this statements

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

then for example the expression *r points to the pointer p. So dereferencing the pointer p like *p that is the same as *( *r ) you will get the lvalue of the variable a.



Answered By - Vlad from Moscow
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to properly deference a char** pointer passed as an address to functions?

 July 06, 2022     c, c-strings, dereference, pass-by-reference, pointers     No comments   

Issue

I am writing a program that uses char ** to setup a multidimensional array. I then pass the address of the char ** to another function to play with.

How do I properly deference ** pointers after they have been passed via address to another function?

ERROR
array of c string
Segmentation fault

int test(char *** strings){
    puts(*strings[0]);
    puts(*strings[1]);
    return 1;
}

int main(void) {

    char arr[][25] =
    { "array of c string",
    "is fun to use",
    "make sure to properly",
    "tell the array size"
    };
    
    
  char ** strings = (char**)malloc(2 * sizeof(char*));
  
  strings[0] = (char*)malloc(25 * sizeof(char));
  strcpy(strings[0], arr[0]);
  
  strings[1] = (char*)malloc(25 * sizeof(char));
  strcpy(strings[1], arr[1]);
  
  test(&strings);

  return 1;
}

*Mallocs are casted incase someone plugs this into a C++ playground


Solution

This works:

int test(char *** strings){
    puts((*strings)[0]);
    puts((*strings)[1]);
    return 1;
}

Because [] binds more tightly than * and you need to dereference first. See https://en.cppreference.com/w/c/language/operator_precedence



Answered By - user14215102
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing