Oersted
Oersted

Reputation: 2734

Does std::bit_cast incur an overhead?

I'm looking for legit use-cases of std::bit_cast in my code bases. Yet current cppreference documentation makes me wonder if it may induce an overhead by creating a (named) temporary object (thus not subject to mandatory copy/move elision).

Looking at the standard, It also says it returns a plain object that must be copied.

Is there really an overhead, what is the gain with respect to a mere std::memcpy to an existing object?

As an illustration, here is a contrived example where, ASFAIU, the std::bit_cast seems to imply much more assembly than the std::memcpy (not the best metric but I couldn't find an easiest way to illustrate my question):

//header.h
#ifndef HEADER
#define HEADER
#include <array>

class S {
   public:
    int val[1024] = {-1};
};

void SetBC(S& s,const std::array<char,sizeof(S)>& arr);
void SetMC(S& s,const std::array<char,sizeof(S)>& arr);

#endif

// main.cpp
#include "header.h"
#include <bit>
#include <cstring>

void SetBC(S& s,const std::array<char,sizeof(S)>& arr)
{
    s = std::bit_cast<S>(arr);
}
void SetMC(S& s,const std::array<char,sizeof(S)>& arr)
{
    std::memcpy(&s,arr.data(),sizeof(S));
}

Upvotes: 4

Views: 146

Answers (1)

user17732522
user17732522

Reputation: 76829

As an illustration, here is a contrived example where, ASFAIU, the std::bit_cast seems to imply much more assembly than the std::memcpy (not the best metric but I couldn't find an easiest way to illustrate my question):

The functions SetBC and SetMC can be compiled to identical assembly. If a compiler isn't doing that, it is a bug (in the sense of missed optimizations) in the compiler.

Looking at the standard, It also says it returns a plain object that must be copied.

Returning an object by value is a benefit over memcpy. It permits using the result to initialize a variable or returning it in a return statement, so that mandatory copy elision applies and it becomes unnecessary to first define and initialize a variable of the target type with some temporary state before storing the intended value in it.

Because you use an out-parameter in your example function, you lose that benefit again. If you attempt to rewrite the functions to return-by-value, you will see that the std::bit_cast version will be better.

Also, std::bit_cast is type-safe and can be used at compile-time. Both are further benefits over memcpy.

Upvotes: 1

Related Questions