3
Parzi
5y

i've been banned from SO again because too many people hit downvote on my shit without telling me why, so i'll ask in short here:

How the fuck are u64* and u64 different, why can't I cast between them or between them and a double and why the fuck is C gay?

Now, again but longer:

https://stackoverflow.com/questions...

Comments
  • 3
    it was closed and deleted for being off-topic so here's the full question:

    """

    I'm trying to port things written into C to platforms they're not intended for, and as part of this, I have a function, equivalent to the normally-used function, that returns u64* instead of a double. Further down in the code, this becomes a problem, as the code tries to multiply a double by one of the u64* vars. Is there any way to cast between these? I can't find anything on type u64* as search engines don't like the asterisk, so this question may be a duplicate of something I can't search for. I've tried casting u64* to u64, which doesn't work.

    """
  • 7
    It's just a matter of...perspective

    Or

    That's left up to... Interpretation

    Ok, jokes aside:
    If it's a pointer to a u64, just deref it, no need to cast. Doubles at u64 sizes will be inaccurate because they can't represent the full size and will round.

    What datatype do you actually need?
  • 1
    @SortOfTested I have to multiply it with a double as part of the return. I'm trying to port other people's code to the PS3, so I can't really just change that as if I do nothing works anymore.
  • 4
    Read about pointers.
  • 3
    "why the fuck is C gay?" I love this
  • 3
    u64 known as "unsigned long long int" and u64* is a pointer to a "u64" (so basically the asterisk signifies a pointer)

    Example usage
    ---------------------------
    @highlight
    u64 foo = 0;
    // A pointer holding the address of foo not the value
    u64* bar = &foo;
    bar = 10; // Indirectly sets the value of foo to 10 because it has the address

    printf('%lu\n',foo); // prints out 10
    printf('%x\n', bar); // prints address of foo
    printf('%lu',*bar); // prints out 10

    // Re-initialize a u64 variable from the pointer *bar
    // No casting is needed
    u64 foobar = *bar;
    printf('%lu',foobar); // prints out 10
  • 3
  • 3
    Why the hell is this function returning a pointer to a u64 instead of a double? Did you write it? If not, you need some documentation on its return value. Sounds like you wanna deref it and then cast that value to a double. But I'm just assuming that this function returned a pointer to avoid a pass by value. Maybe it's supposed to be an array. You should find that documentation.

    Anyway you can't cast it to double because you don't want some random memory address as a double. Unless some idiot decided to store a value as a pointer. If that idiot's you, stop doing that.
  • 2
    No wonder that this gets closed on SO.

    @GiddyNaya There's a bug, it has to be *bar=10.
  • 2
    @Fast-Nop ure right, C is a demonic beast when it comes to pointers though.
  • 3
    @GiddyNaya GCC would warn on this even without -Wall / -Wextra. If using -Werror, that would also abort compilation right away. So that kind of typo would be easy to detect in practice.
  • 7
    to be honest with you, unless you're a complete C newbie who started learning it 24 hours ago, it really is kind of a dumb question. "what is the difference between pointer to a variable and a variable itself and why can't i cast between them?"

    about the same as the difference between a city and a road sign pointing to a city, and for the same reason why you can build a house in a city, but you can't build a house in a road sign pointing to a city...

    i have never even programmed in any language that does c-style pointers, but even i know that...
  • 2
    Yeah, do a C tutorial that teaches about pointers before going on SO and being downvoted. It is a bit toxic of a forum, but this one isn't on the community, it's on you.
  • 0
    @Midnight-shcode @Lor-inc @Fast-Nop @GiddyNaya @gronostaj Yes, i'm new to C, what of it?
    (Well, "new", i've been beating my head on the wall that is C for years, but managed to do fuck all with it.)

    @M3m35terJ05h no, just the worst toolchain in existence... https://github.com/ps3dev/PSL1GHT/...
  • 2
    @Parzi Being new to C is perfectly fine, but SO isn't a tutorial. Such a question is better addressed by working through a basic tutorial and doing the pointer exercises.
  • 1
    @Parzi Jesus Christ what the hell is going on in there
  • 1
    @Parzi The code actually makes sense because that's diving right into assembly calls. The thing is that the syscall takes the parameters as u64, probably in some registers. That's why the pointer is converted to a u64.

    But there's no "double" involved?!
  • 0
    @Fast-Nop ah, y'see, that's where we hit https://github.com/libretro/...
    That "1e-9" is considered a double.

    @M3m35terJ05h most of the chain is like that, and there's no docs to boot. (Well, there are, but there's 2 pages on a website for SPU management and nothing else, which is much less than needed.)
  • 1
    @Parzi Time as double really sucks. But OK, still no big issue - it's just that the "double" result can't be used with the syscalls. The syscalls need the data from that tv struct.
  • 0
    @Fast-Nop the tv struct is dual-double when not on Windows.
  • 1
    @Parzi I guess they're instead long integer, i.e. i32, see line 62. Ah ok on Windows.

    Yeah OK, then you can get the integer part of the doubles and use that one, i.e. convert the two parts back to integers.
  • 1
    @Fast-Nop yes, but this isn't Windows, so that's preprocessed out and doesn't apply.
  • 0
    @Parzi Where's the actual definition of the timespec struct for non-Windows? Should be somewhere in the toolchain itself I guess.
  • 0
    @Fast-Nop The toolchain is 100% non-standard, so it's probably not. I don't know where it's at for non-Windows.
  • 1
    @Parzi Yeah I took a look at it, and to even install it looks like a nightmare of dependencies from all-over, and then some patches for GCC & Co that may or may not work.

    But anyway, since a double can easily hold all whole numbers that fit into an i32, you can just get that back.

    The one gotcha is that you can't type pun through pointers directly because that's undefined behaviour. So you can't take the address of a double and try to read that as integer. But you can read it as double from the pointer and cast the data to integer, that works.

    Basically just reverting the 1e-9 multiplikation and splitting back into the two original parts.
  • 1
    @TheCommoner282
  • 1
    @Fast-Nop it's actually got installscripts that are fairly okay, and are way better made than the chain itself: set a few environment vars, run some sh scripts that download and compile it for you, and go. Only issue I had was that I couldn't use a for loop in bash to run them all unattended as it segfaulted for some reason, but when I did them manually, it worked fine.

    Also, would you mind elaborating on your solution?
  • 0
    @TheCommoner282 I'll keep that in mind whenever I decide to use it ever again.
  • 1
    @Parzi Under Windows and Linux, the timespec is two i32, that's common. If it's two doubles, just check how they are calculated with the 1e-9, do that calculation in the other direction, and you should get the original values back as integers. Basically, just a wrapper that converts the data format.
  • 0
    @Fast-Nop it's *normally* 2 doubles, how would that help me with this? I don't know what the 1e-9 calculation is even supposed to do, and the main issue is just un-pointering the u64's.
  • 1
    @Parzi You mean inside that syscall from system.h line 23? But there's no double, these are pointers u64* that got converted into u64?

    So inside that syscall for call 145 ONLY you'd cast the u64 back into u64* and then dereference that.

    Something like *((u64*) para) would do if para is one of these u64 that were originally u64* before the cast in line 23. That gives you the actual u64 behind it (no double).
  • 1
    @Fast-Nop I'll give that a try.
Add Comment