Hard coded array access of multiple indexes always sets my teeth on edge past the first two or so. Call it "a bad code smell", call it "some old fart being retentive", whatever.
It's easy to turn this into a loop, so here it is. If your compiler decides to unroll it, then it'll do a better job than your or I could have anyway. That unrolled loop just might look like one of the other answers, but I wouldn't count on it.
uint64_t AppendBytes64(uint8_t* val, int start)
{
uint64_t total = 0;
for (int i = 0; i < 8; ++i)
{
uint64_t bigByte = val[start + i];
total <<= 8;
total += bigByte;
}
return total;
}
int main() {
uint8_t data[] = { 0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0 };
uint64_t result = AppendBytes64(data, 0);
printf("%llx\n", result);
return 0;
}
The above code prints:
0102030000000000
Which is what I expected, and what I was going for initially. My off-the-cuff answer was closer to "correct" than I thought. Now if you want a different "endianess", that's a whole other problem.
Yep, and upon further reading of the question, the original poster did indeed want the other endianess, so more of a requirements translation problem rather than a "bug" per se.
None the less, the answer was still wrong, as pointed out in the comments. It's funny seeing this when I so often get on my son's case when working with him on his math homework about answering the question that was actually asked versus that conclusion you just jumped to. "Sins of the father" indeed.
So if the first byte is the least significant, then we instead write AppendBytes64 thusly:
uint64_t AppendBytes64(uint8_t* val, int start)
{
uint64_t total = 0;
for (int i = 7; i >= 0; --i)
{
uint64_t bigByte = val[start + i];
total <<= 8;
total += bigByte;
}
return total;
}
Which prints:
030201
This again is hex, only this time it's also the desired output.
Which brings up an interesting point. There's almost certainly an existing endian function in an existing library that will do this for you. I'm pretty sure this is a "little endian to native" function... which means that it'll break if the underlying native endian doesn't match my own. After a brief reading on the endian library docs, I suggest going with boost::endian::little_uint64_buf_t, which supports >> for pulling consecutive uint64's out of a stream of little endian bytes.
Of course I often get little and big endian backwards, but I think I actually have it right this time (but when don't I?!).