#Casting int to unsigned char[4]
77 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
unsigned char uc_num1 = (unsigned char) num1;
perhaps?
what are you trying to do that requires that?
that casts a single int to a single unsigned char, not 4
I am reading an existing file where some data is being stored as a single int but is actually four chars encoded into a single int. For example 33752065 is actually char{2,3,4,1}
in this case 00000010000000110000010000000001b = 33752065 but it should be read as 00000010b 00000011b 00000100b 00000001b = 2 3 4 1
using std::memcpy: https://en.cppreference.com/w/cpp/string/byte/memcpy
example:
#include <cstring>
#include <iostream>
int main ()
{
int a {1000};
unsigned char data [4] {};
std::memcpy (&data, &a, 4);
for (const auto c : data)
{
std::cout << +c << ' ';
}
}
that's what I was about to suggest
I would toss in a static_assert(sizeof(int) == 4) to be safe to make sure you validate your assumption
or use std::int32_t I guess instead of int
I think the quickest solution would be
char charArray[4];
int* intPointer = reinterpret_cast<int*>(&charArray[0]);
int integer = *intPointer;
but do this ONLY if charArray size is always a multiple of 4! Else it can result in a bad behavior.
no, don't do this
why not
until it doesn't, obviously, because it's UB
what should UB be?
int* intPointer = reinterpret_cast<int*>(&charArray[0]);
idk what UB means so idk
undefined behavior
how so
tl;dr stuff that's not allowed by the language
char[] is an array
the stuff you posted is as allowed as dividing by zero
or indexing out of bounds
type punning (the thing you posted) violates strict aliasing rules, and generally isn't allowed by the language, whereas memcpy is an allowed construct and in the simple cases it will compile down to what you tried to write
okay again what isn't allowed there? Like which computer rule it violates?
it's a language rule
meaning the compiler, since it assumes you respect language rules, may emit invalid "instructions"
or "instructions" that doesn't behave the way you would expect it to behave
you have literally an index to the first bit of char[4]
an array is internal constructed at begin with the type and then with the concret bits of the array, no waste informations.
so if you point to the first char and reinterpret the information, then you can call the informations of 4x8 bits (int), instead of 1x8 bits (char) ... how is that "bad"?
well the compiler rule yeah
I literally just told you, it's strict aliasing rules
then why the hell reinterpret_cast exists?
that's not how the language works
for other cases, and those are rare and few cases where they come up, which is part of why generally speaking if you need reinterpret_cast it often means you're doing something wrong, or have to deal with something someone else did wrong
or there are no other better constructs available so you willingly decide to eat the UB but if you do that normally you throw a bunch of tests and coverage at it to make as sure as possible that you detect any breakage as early as possible
the language is definitely not binary at all
the language has rules, rules that you have to follow
indexing out of bounds is UB by language design, and the consequence of it are varied at runtime
even just looking at the "binary"
no but thats how the stuff is stored
this is like calling sizeof on a pointer...
It sometimes works, ofc. If your data is the same size as a pointer is...
and the code that accesses whatever is "stored" is produced by the compiler, which is free to not at all access anything if by language rules or any optmization it assess that that shouldn't be necessary, invalidating any mental model you had to would rely on "accessing/reading" the memory
and even if everything happened to work well, if it's fobidden by the language it is forbidden by the language
and this kind of "type punning" is not uncommon to encounter in the wild, but if you have other options then the general recommendation is to just use the other option
yep, if you can do it it doesn't mean you should
because this specific kind of "type punning" doesn't have great alternatives, except that in OP's case it has
it's memcpy
and if you want a poster child, short, simplified to the point of being stupid, example of a compiler doing an optimization that produces "nonsense"
then just do
char charArray[N*4];
int intArray[N];
for(size_t i = 0; i < N*4; i++)
intArray[i/4] += charArray[i] << ((i%4)*8);
wait op just wants to convert an int into a char array?
;compile -O2
#include <iostream>
int foo( float *f, int *i ) {
*i = 1;
*f = 0.f;
return *i;
}
int main() {
int x = 0;
std::cout << x << "\n"; // Expect 0
x = foo(reinterpret_cast<float*>(&x), &x);
std::cout << x << "\n"; // Expect 0?
}
yes
0
1
or just literally use memcpy
wtf is memcpy
by that do we man we want to convert 1234 to ['1' , '2' , '3' , '4'] ?
...
not quite, no
they want the actual bytes
see this
well then, memcpy
void* memcpy(
void* dest,
const void* src,
size_t count);
// ... and 2 more
<string.h>
copies memory from one adress to another basically...
;compile
#include <iostream>
#include <cstring>
int main() {
int i = 33752065;
unsigned char ac[sizeof(int)];
std::memcpy(ac, &i, sizeof(int));
for (auto const c : ac)
std::cout << static_cast<int>(c) << ' ';
}
1 4 3 2
I forgot we are doing cpp as soon as memcpy was mentioned haha, at least we have foreach
your code is interpreted by the compiler, so when you violate the compilers rules it doesn't have to generate the code that follows your interpretation of what should happen
you should read each byte from the file and then use the bitwise operators to construct the value that you want