Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid implicit copy in ptr::addr_of() #2040

Closed
dram opened this issue Mar 21, 2012 · 7 comments
Closed

avoid implicit copy in ptr::addr_of() #2040

dram opened this issue Mar 21, 2012 · 7 comments
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system C-cleanup Category: PRs that clean code up or issues documenting cleanup.
Milestone

Comments

@dram
Copy link

dram commented Mar 21, 2012

I wonder if there is any use for ptr::addr_of() to return address of a temporary copied version of its argument, but it seems a bit annoying. E.g. for following code, different address will be printed.

fn main() {
        let foo = 1;

        log(error, addr_of(foo));
        log(error, addr_of(foo));
}

Use following version of addr_of instead, the address will be consistent.

fn addr_of<T>(&val: T) -> *T { ret ptr::addr_of(val); }

And a real world example:

fn get_elem(mixer: snd_mixer, name: str) -> snd_elem {
    let sid = null();

    asound::snd_mixer_selem_id_malloc(addr_of(sid));

    asound::snd_mixer_selem_id_set_index(sid, 0);

    as_c_str(name) {|buf|
        asound::snd_mixer_selem_id_set_name(sid, buf);
    }

    ret asound::snd_mixer_find_selem(mixer, sid);
}

asound::snd_mixer_selem_id_malloc() will allocate a buffer and assign the address to sid。But as sid is implicit copied, sid remains 0 after this function call.

Can ptr::addr_of() be defined as always pass by reference to avoid implicit copy?

@nikomatsakis
Copy link
Contributor

This is the current behavior. addr_of<T>(t: T) will pass by reference because type variables (T) are passed by reference by default (as are scalars and non-unique pointers).

@marijnh
Copy link
Contributor

marijnh commented Mar 21, 2012

What you were seeing here -- with the two different addresses being shown -- is produced by the fact that an immediate value that's not assigned to does not get spilled to the stack. So the calls were doing their own spilling to be able to pass it by reference, each producing a different address. Your & approach helped because passing something by mutable reference counts as assigning to it, forcing it to be spilled.

This is all rather confusing. We'll soon be overhauling the way function argument passing works, and in the process will have to rethink the way addr_of takes its arguments as well.

@brson brson reopened this Mar 21, 2012
@brson
Copy link
Contributor

brson commented Mar 21, 2012

This does seem like a real issue. C doesn't exhibit this behavior, does it?

@marijnh
Copy link
Contributor

marijnh commented Mar 21, 2012

C forces locals to be stack-allocated when you take their address. I'm going to make addr_of something that the compiler knows about as part of the work on #1981. I can take a stab at properly fixing this too.

@ghost ghost assigned marijnh Mar 21, 2012
@nikomatsakis
Copy link
Contributor

Regions let you take the address using the & operator, also.

@marijnh
Copy link
Contributor

marijnh commented Mar 21, 2012

That actually sounds like a much better approach. So I guess we'd have addr_of take a reference to some thing? Or do you think we should make a variant of the & operator that returns an unsafe pointer right away?

@graydon
Copy link
Contributor

graydon commented Mar 21, 2012

I think &foo as *bar ought to be an unsafe (but legal) operation, and we can parcel it up as addr_of<T> if someone feels the cast is too clunky.

bors added a commit to rust-lang-ci/rust that referenced this issue May 2, 2020
…-float-functions, r=flip1995

Add lint to improve floating-point expressions

Looks for floating-point expressions that can be expressed using built-in methods to improve accuracy, performance and/or succinctness.

changelog: Add lint `floating_point_improvements`.

Fixes rust-lang#4726
Partly addresses [rust-lang#2040](rust-lang/rust-clippy#2040)

Currently linted expressions:

| Expression | Suggestion |
|---------------------------------|------------|
| x.log(2.0) | x.log2() |
| x.log(10.0) | x.log10() |
| x.log(std::f32::consts::E) | x.ln() |
| (1 + x).ln() | x.ln_1p() |
| (2.0).powf(x) | x.exp2() |
| (std::f32::consts::E).powf(x) | x.exp() |
| x.powf(1/2) | x.sqrt() |
| x.powf(1/3) | x.cbrt() |
| x.powf(y), where y is whole | x.powi(y) |
| x.exp() - 1 | x.exp_m1() |
|x * y + z|x.mul_add(y, z)|
flip1995 added a commit to flip1995/rust that referenced this issue Jul 14, 2020
Some accuracy lints for floating point operations

This will add some lints for accuracy on floating point operations suggested by @clarfon in rust-lang#2040 (fixes rust-lang#2040).

These are the remaining lints:

- [x] x.powi(2) => x * x
- [x] x.logN() / y.logN() => x.logbase(y)
- [x] x.logbase(E) => x.log()
- [x] x.logbase(10) => x.log10()
- [x] x.logbase(2) => x.log2().
- [x] x * PI / 180 => x.to_radians()
- [x] x * 180 / PI => x.to_degrees()
- [x] (x + 1).log() => x.log_1p()
- [x] sqrt(x * x + y * y) => x.hypot(y)

changelog: Included some accuracy lints for floating point operations
celinval pushed a commit to celinval/rust-dev that referenced this issue Jun 4, 2024
Co-authored-by: rahulku <luhark@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lifetimes Area: Lifetimes / regions A-type-system Area: Type system C-cleanup Category: PRs that clean code up or issues documenting cleanup.
Projects
None yet
Development

No branches or pull requests

5 participants