Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 74167
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T20:18:57+00:00 2026-05-10T20:18:57+00:00

In an Open Source program I wrote , I’m reading binary data (written by

  • 0

In an Open Source program I wrote, I’m reading binary data (written by another program) from a file and outputting ints, doubles, and other assorted data types. One of the challenges is that it needs to run on 32-bit and 64-bit machines of both endiannesses, which means that I end up having to do quite a bit of low-level bit-twiddling. I know a (very) little bit about type punning and strict aliasing and want to make sure I’m doing things the right way.

Basically, it’s easy to convert from a char* to an int of various sizes:

int64_t snativeint64_t(const char *buf)  {     /* Interpret the first 8 bytes of buf as a 64-bit int */     return *(int64_t *) buf; } 

and I have a cast of support functions to swap byte orders as needed, such as:

int64_t swappedint64_t(const int64_t wrongend) {     /* Change the endianness of a 64-bit integer */     return (((wrongend & 0xff00000000000000LL) >> 56) |             ((wrongend & 0x00ff000000000000LL) >> 40) |             ((wrongend & 0x0000ff0000000000LL) >> 24) |             ((wrongend & 0x000000ff00000000LL) >> 8)  |             ((wrongend & 0x00000000ff000000LL) << 8)  |             ((wrongend & 0x0000000000ff0000LL) << 24) |             ((wrongend & 0x000000000000ff00LL) << 40) |             ((wrongend & 0x00000000000000ffLL) << 56)); } 

At runtime, the program detects the endianness of the machine and assigns one of the above to a function pointer:

int64_t (*slittleint64_t)(const char *); if(littleendian) {     slittleint64_t = snativeint64_t; } else {     slittleint64_t = sswappedint64_t; } 

Now, the tricky part comes when I’m trying to cast a char* to a double. I’d like to re-use the endian-swapping code like so:

union  {     double  d;     int64_t i; } int64todouble;  int64todouble.i = slittleint64_t(bufoffset); printf('%lf', int64todouble.d); 

However, some compilers could optimize away the ‘int64todouble.i’ assignment and break the program. Is there a safer way to do this, while considering that this program must stay optimized for performance, and also that I’d prefer not to write a parallel set of transformations to cast char* to double directly? If the union method of punning is safe, should I be re-writing my functions like snativeint64_t to use it?


I ended up using Steve Jessop’s answer because the conversion functions re-written to use memcpy, like so:

int64_t snativeint64_t(const char *buf)  {     /* Interpret the first 8 bytes of buf as a 64-bit int */     int64_t output;     memcpy(&output, buf, 8);     return output; } 

compiled into the exact same assembler as my original code:

snativeint64_t:         movq    (%rdi), %rax         ret 

Of the two, the memcpy version more explicitly expresses what I’m trying to do and should work on even the most naive compilers.

Adam, your answer was also wonderful and I learned a lot from it. Thanks for posting!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T20:18:57+00:00Added an answer on May 10, 2026 at 8:18 pm

    Since you seem to know enough about your implementation to be sure that int64_t and double are the same size, and have suitable storage representations, you might hazard a memcpy. Then you don’t even have to think about aliasing.

    Since you’re using a function pointer for a function that might easily be inlined if you were willing to release multiple binaries, performance must not be a huge issue anyway, but you might like to know that some compilers can be quite fiendish optimising memcpy – for small integer sizes a set of loads and stores can be inlined, and you might even find the variables are optimised away entirely and the compiler does the ‘copy’ simply be reassigning the stack slots it’s using for the variables, just like a union.

    int64_t i = slittleint64_t(buffoffset); double d; memcpy(&d,&i,8); /* might emit no code if you're lucky */ printf('%lf', d); 

    Examine the resulting code, or just profile it. Chances are even in the worst case it will not be slow.

    In general, though, doing anything too clever with byteswapping results in portability issues. There exist ABIs with middle-endian doubles, where each word is little-endian, but the big word comes first.

    Normally you could consider storing your doubles using sprintf and sscanf, but for your project the file formats aren’t under your control. But if your application is just shovelling IEEE doubles from an input file in one format to an output file in another format (not sure if it is, since I don’t know the database formats in question, but if so), then perhaps you can forget about the fact that it’s a double, since you aren’t using it for arithmetic anyway. Just treat it as an opaque char[8], requiring byteswapping only if the file formats differ.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 75k
  • Answers 75k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • added an answer You need to use Workbook.SaveAs instead of Application.Save: Excel.Application app… May 11, 2026 at 2:48 pm
  • added an answer This should do it: <%= f.select :project_id, @project_select, :selected =>… May 11, 2026 at 2:48 pm
  • added an answer Java programmers in general tend to be very consistent about… May 11, 2026 at 2:48 pm

Related Questions

In an Open Source program I wrote , I'm reading binary data (written by
When I realized I needed to create an index for approximately 50 XHTML pages,
I am writing a fairly large and complex data analysis program and I have
Let's say there's a.gz, and b.gz. $ gzip_merge a.gz b.gz -output c.gz I'd like
Have you ever been frustrated by Visual Studio not re-evaluating certain watch expressions when

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.