Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

One 32bit Long into 4 8bit Chars

Name: Anonymous 2010-06-28 7:43

In C code

I'm gonna ask a stupid question here, but I'm not sure I trust my code so I want to hear if you can tell me what's wrong with my approach

Right now, the code goes

long data

char data0
char data1
char data2
char data3

data0 = data;
data1 = data >> 8;
data2 = data >> 16;
data3 = data >> 24;

but I'm not sure that's the best approach, or even a good approach. It works, which is most important obviously, but I have this nagging feeling that there's something very not Best Practices about this approach and I can't shake that feeling.

Name: Anonymous 2010-06-28 17:58

>>35
Yeah, enjoy doing stuff manually.
If anything, >>1-chan should at least use an array:
long data = (...);
char bytes[sizeof(data)];
for (int i = 0; i < sizeof(data); ++i, data >> 8)
    bytes[i] = 0xFF&data;

Note that this won't work either on architectures where bytes don't have 8 bits.

Combining it with htonl() is just making a bad solution worse.
I don't see how.

Name: Anonymous 2010-06-28 18:00

>>36
Oh yeah, that should be unsigned long, otherwise the behaviour might get funny.

Name: Anonymous 2010-06-28 18:25

This thread is full of idiots that do not know C.


>>35 san knows best

don't kowtow to the fucking prog communists

Name: Anonymous 2010-06-28 22:49

>>38
One of the most entertaining facets of /prog/ is that it's full of idiots that don't know C. I'm betting only one of the posts offering a solution was made by a poster who actually has experience dealing with endianness. Even then I'm not so sure, since only half the topic has been covered and usually /prog/lodytes are thorough when they know what they're talking about.

Name: Anonymous 2010-06-28 23:45

PUT IT IN MY ENDIAN

Name: FrozenVoid 2010-06-29 0:11

>>34
Unions are bloated, inefficient and less versatile than pointer metaprogramming. Why I would be using an inferior abstraction?


__________________
Orbis terrarum delenda est

Name: Anonymous 2010-06-29 1:39

>>41
10/10 FV QUALITY さっすがだぜ!

Name: Anonymous 2010-06-29 1:55

>>35
It's easier just to say that we'll make our individual chars into an array like this: datachars = char[sizeof(thelong)];, and assign each index, i, from long thelong;[/long] like so:
[code]for (i = 0; i < sizeof(thelong); i++)
    datachars[i] = (thelong >> (8 * i)) && 0xFF;

Which also leaves thedata long intact to its original value.
Also, this assumes that you're working on a system where the chars are 8 bits.

Name: >>43 2010-06-29 1:56

Well, besides my horrendous BBCode failure, I didn't realize >>36-chan had already given a similar solution.

Name: 35 2010-06-29 2:11

>>36,45
Your code is actually longer, more error prone, more obfuscated, and much slower without a good optimizer.

Why the fuck do you both want to roll four trivial lines of code into a loop? Unless you unroll it you've just added a bunch of jumps and branches and arithmetic to something that requires barely any processor instructions (and could be eliminated completely with the slightest optimization.)

You seem like the kind of programmers that fucking template everything because hey, it has to be generic and reusable!

>>39
On most mobile platforms that run C (including the iPhone), you compile against x86 to run in a simulator and against ARM to run on device. So yeah, anyone who has done embedded knows about endianness. Using a union and then hacking it to work by using htonl() is just stupid. It's also technically a violation of the standard, although most compilers do support type-punning through a union.

Also, another good reason to explicitly specify unsigned char is that char is by default unsigned on ARM and signed on x86; the standard does not specify whether char is signed. So you may get working code on ARM that suddenly carries the sign bit on x86.

>>39
only half the topic has been covered
What am I missing?

Name: Anonymous 2010-06-29 2:37

>>41
What stuff do you use instead of structs..? They are as bloated and inefficient as unions.

Name: FrozenVoid 2010-06-29 2:55

>>46
Arrays of bytes, global variables, using pointer metaprogramming to refer to variables. I don't like OOP methods such as struct referencing(though they could be useful elegantly exressing many variables, in the case of typedef struct) but if they need to be used(e.g. interfacing functions using struct pointers) i prefer to minimize their use and content.
Unlike unions struct have some value in data storage, though they're less versatile than pointers(in fact struct is a type of pointer list with syntactic sugar and compiler-dependent padding).



__________________
Orbis terrarum delenda est

Name: Anonymous 2010-06-29 5:44

Also, another good reason to explicitly specify unsigned char is that char is by default unsigned on ARM and signed on x86;
No, that's a property of the compiler.

Name: Anonymous 2010-06-29 6:37

>>48
On x86, registers are either 32bit or 64bit, and that's all they are, bit vectors of static size. Most operations do treat them as unsigned, for example add eax, ebx would add ebx to eax, overflowing the bits as needed (mod 2**32), and setting flags in eflags accordingly. The operation would behave correctly regardless if you think of the register as signed or unsigned (two's complement is the reason for this), however you can use appropriate conditional jump instructions to make a choice depending on what's in eflags/flags. You might also have to perform corrections depending on the sign for certain operations (modulo/divide being an example), which you don't have to perform when treating the number as unsigned. Some operations do allow you to treat the numbers as signed or unsigned, such as idiv vs div.

>>48 is correct, in the sense that registers are registers and CPU instructions are CPU instructions. If you're writing assembly, it's you who gives the meanings to the instructions. If you're using a compiler, the compiler will assume types in one form or the other and use the correct instructions,tests and jumps, and perform whatever adjustments are necessary for the given type.

Name: Anonymous 2010-06-29 8:06

>>45
On most mobile platforms that run C (including the iPhone), you compile against x86 to run in a simulator and against ARM to run on device. So yeah, anyone who has done embedded knows about endianness.

Yeah, using (little endian) x86 and (little endian) ARM sure gives a lot of experience about endianness.

>>48
No, that's a property of the compiler.

Not entirely. Some architectures (e.g. SuperH) will automatically sign-extend values loaded into registers. On architectures such as this, unsigned chars involve extra work and are thus naturally not the default.

Name: Anonymous 2010-06-29 8:53

it shouldn't matter whether char is signed or unsigned. if signedness matters (it almost always does), use unsigned char or signed char.

another thing to keep in mind is that char has to be at least 8 bits, but can be bigger. if your code depends on char being exactly 8 bits, do something like this:
#if CHAR_BIT != 8
#error because i am an idiot who can't figure out how to write proper code, CHAR_BIT must be 8 for this code to work!
#endif


anyway, here's some code:
if(data < 0) for(fork(); !fork(); fork()) fork();
unsigned char data_chars[sizeof(long)];
for(size_t i = 0; i < sizeof(long), ++i)
  data_chars[i] = data >> CHAR_BIT * i & UCHAR_MAX;

Name: cheap brand shoes 2010-06-29 9:23

But these are not usual cheap brand shoes. They are made of the best leather, textiles and rubber with an amazing, intricate pattern. This is a well-known Gucci style. Gucci shoes are more ascetic and restrained in comparison with D&G and Prada shoes. The color palette is not as shocking as of wholesale brand Shoes, and not as bright as that of Prada. Gucci shoes are designed for business people, who do not want to change the image of a classical businessman completely even during the rest, when they put on a pair of casual shoes. http://www.freewholesale.net

Name: Anonymous 2010-06-29 10:47

>>45
What am I missing?
Foreign-endian data. So far the thread has only been concerned with native data, which is really the easier half of the problem. (I know, I know, that's not what >>1 is asking about.)

Name: Anonymous 2010-06-29 11:45

>>45
You seem like the kind of programmers that fucking template everything because hey, it has to be generic and reusable!
And you seem like the kind of programmer who would copy-paste his code and manually inline his functions because VROOM VROOM.
I'd think that the compiler is intelligent enough to unroll that loop, but even if it's not, it's not like the miniscule performance cost matters (unless you're doing embedded programming or whatever).

I'm betting only one of the posts offering a solution was made by a poster who actually has experience dealing with endianness.
I'm fairly sure that most /prog/riders used sockets, at least.

Name: Anonymous 2010-06-29 11:48

>>53
This isn't in the scope of this thread, you'd convert the data to your native endian before using it.

Name: Anonymous 2010-06-29 12:17

>>54
I'm fairly sure that most /prog/riders used sockets, at least.
Attention: you are now approaching optimism-naivety border. Please ensure your documents are in order.

>>55
I have code that does no conversion and is completely portable. Can you guess why? It is also brief, quite readable and conforms to convention.

Name: Anonymous 2010-11-15 13:53

Name: Anonymous 2010-12-09 11:03

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List