Datsik
Datsik

Reputation: 14824

Is there an equivalent to C's *(unsigned int*)(char) = 123 in Javascript?

I'm dealing with some C source code I'm trying to convert over to Javascript, I've hit a snag at this line

char ddata[512];
*(unsigned int*)(ddata+0)=123;
*(unsigned int*)(ddata+4)=add-8;
memset(ddata+8,0,add-8);

I'm not sure exactly what is happening here, I understand they're casting the char to an unsigned int, but what is the ddata+0 and stuff doing here? Thanks.

Upvotes: 4

Views: 419

Answers (2)

chqrlie
chqrlie

Reputation: 144780

The code fragment is storing a record id (123) as 4 byte integer in the first 4 bytes of a char buffer ddata. It then stores a length (add-8) in the following 4 bytes and finally initializes the following add-8 bytes to 0.

Translating this to javascript can be done in different ways, but probably not by constructing a string with the same contents. The reason is strings a not byte buffers in javascript, they contain unicode code points, so writing the string to storage might perform some unwanted conversions.

The best solution depends on your actual target platform, where byte arrays may be available to more closely match the intended semantics of your C code.

Note that the above code is not portable and has undefined behavior for various reasons, notably because ddata might not be properly aligned to be used as the address to store an unsigned int via the cast *(unsigned int*)ddata = 123;, because it assumes int to be 4 bytes and because it relies on unspecified byte ordering.

On the Redhat linux box it probably works as expected, and the same C code would probably perform correctly on MacOS, that uses the same Intel architecture with little endian ordering. How best to translate this to Javascript requires more context and specifications.

In the mean time, the code would best be rewritten this way:

unsigned char ddata[512];
if (add <= 512) {
    ddata[0] = 123;
    ddata[1] = 0;
    ddata[2] = 0;
    ddata[3] = 0;
    ddata[4] = ((add-8) >> 0) & 255;
    ddata[5] = ((add-8) >> 8) & 255;
    ddata[6] = ((add-8) >> 16) & 255;
    ddata[7] = ((add-8) >> 24) & 255;
    memset(ddata + 8, 0, add - 8);
}

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234715

You can't say.

That's because the behaviour on casting a char* to an unsigned* is undefined unless the pointer started off as an unsigned*, which, in your case it didn't.

ddata + 0 is equivalent to ddata.

ddata + 4 is equivalent to &ddata[4], i.e. the address of the 5th element of the array.

For what it's worth, it looks like the C programmer is attempting to serialise a couple of unsigned literals into a byte array. But the code is a mess; aside from what I've already said they appear to be assuming that an unsigned occupies 4 bytes, which is not necessarily the case.

Upvotes: 3

Related Questions