kandi X-RAY | bit_cast Summary
kandi X-RAY | bit_cast Summary
bit_cast
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of bit_cast
bit_cast Key Features
bit_cast Examples and Code Snippets
Community Discussions
Trending Discussions on bit_cast
QUESTION
Is it possible to implement something similar to C++20's std::bit_cast
in C? It would be a lot more convenient than using union
or casting pointers to different types and dereferencing.
If you had a bit_cast
, then implementing some floating point functions would be easier:
ANSWER
Answered 2022-Jan-19 at 01:25It is possible in non-standard standard C, thanks to typeof
. typeof
is also a further proposed feature for C23, so it may become possible in standard C23. One of the solutions below makes some sacrifices which allow C99 compliance.
union
Let's look at how the approach using union
works first:
QUESTION
I've been trying to figure out if this is an optimisation bug as it only seems to affect stack variables, and I wonder if there's some incorrect assumptions being made. I have this type which converts to and from a relative offset, and it has been working fine while using reinterpret_cast
, but now I'm moving to static_cast
, it's starting to cause issues in optimised builds. I need to get away from reinterpret_cast
for safety certification reasons, so I don't have the option of keeping it as it is.
ANSWER
Answered 2022-Jan-05 at 14:03Your undefined behaviour is in GetOffset
.
This is how pointer subtraction is defined by the standard:
When two pointer expressions
P
andQ
are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined asstd::ptrdiff
in theheader ([support.types.layout])
- If
P
andQ
both evaluate to null pointer values, the result is0
.- Otherwise, if
P
andQ
both point to, respectively, array elements i and j of the same array objectx
, the expressionP - Q
has the value i - j.- Otherwise, the behavior is undefined.
And here, P
(which has the address of m_object
) and Q
(which has the address of data
) aren't elements of the same array, so this is undefined behaviour.
Addition and subtraction of pointers and integers is also defined in terms of array elements:
When an expression
J
that has integral type is added to or subtracted from an expressionP
of pointer type, the result has the type ofP
.
- If
P
evaluates to a null pointer value andJ
evaluates to 0, the result is a null pointer value.- Otherwise, if
P
points to an array element i of an array objectx
with n elements ([dcl.array]), the expressionP + J
andJ + P
(WhereJ
has value j point to the (possibly-hypothetical) array element i+j ofx
if 0≤i+j≤n and the expressionP - J
points to the (possibly-hypothetical) array element i-j ofx
if 0≤i-j≤n.- Otherwise, the behavior is undefined.
The pointer subtraction happens at offset_address - offset
, where P
is the address of m_offset
and offset
is probably some positive number. m_offset
is the first element of the array, so i-j < 0
So, the compiler can see that GetPtr
returns a pointer relative to the m_offset
(in the char[sizeof(Ptr)]
array that aliases the object), so it cannot equal the address of data
(without UB), and thus an optimizer can replace (rp.get() == &data)
with false
.
When you use ptrdiff_t
, no such restriction on addition or subtraction exists. And though the standard doesn't guarantee that reinterpret_cast(reinterpret_cast(char_pointer) + n) == char_pointer + n
(pointers mapping linearly as you would expect) this is what happens when compiling with gcc on common architectures.
QUESTION
If you want to have different public interfaces for one and the same object, you can use virtual base classes. But those have overhead (memory and space).
...ANSWER
Answered 2021-Dec-06 at 15:14Just make an adapter:
QUESTION
This code to read a uint64_t
as two uint32_t
is UB due to the strict aliasing rule:
ANSWER
Answered 2021-Nov-11 at 18:47QUESTION
#include
#include
#include
struct A {
unsigned int size;
char* buf;
};
struct B {
unsigned long len;
void* data;
};
int main() {
static_assert(sizeof(A) == sizeof(B));
static_assert(alignof(A) == alignof(B));
std::array arrayOfA;
std::span spanOfA{arrayOfA};
std::span spanOfB = std::bit_cast>(spanOfA);
// At this point, is using spanOfB standard compliant?
}
...ANSWER
Answered 2021-Nov-10 at 18:48No. While std::span
in C++23 will be defined such that it must be trivially copyable, there is no requirement that any particular span
has the same layout of span
. And even if it did, you'd still be accessing the objects of type A
through a glvalue of type B
, which violates strict aliasing if A
and B
aren't allowed to be accessed that way. And in your example, they are not.
QUESTION
Starting from C++20 closure types without captures have default constructor, see https://en.cppreference.com/w/cpp/language/lambda:
If no captures are specified, the closure type has a defaulted default constructor.
But what about closure types that capture, how can their objects be constructed?
One way is by using std::bit_cast
(provided that the closure type can be trivially copyable). And Visual Studio compiler provides a constructor for closure type as the example shows:
ANSWER
Answered 2021-Oct-25 at 15:34Since this is tagged language-lawyer
, here's what the C++ standard has to say about all this.
But what about closure types that capture, how can their objects be constructed?
The actual part of the standard that cppreference link is referencing is [expr.prim.lambda.general] - 7.5.5.1.14:
The closure type associated with a lambda-expression has no default constructor if the lambda-expression has a lambda-capture and a defaulted default constructor otherwise. It has a defaulted copy constructor and a defaulted move constructor ([class.copy.ctor]). It has a deleted copy assignment operator if the lambda-expression has a lambda-capture and defaulted copy and move assignment operators otherwise ([class.copy.assign]).
The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below.
The closure type is not an aggregate type. An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing: [unrelated stuff]
Which means that (apart from the unrelated exceptions), the described interface of the lambda as stated is exhaustive. Since no other constructors than the default one is listed, then that's the only one that is supposed to be there.
N.B. : A lambda may be equivalent to a class-based functor, but it is not purely syntactical sugar. The compiler/implementation does not need a constructor in order to construct and parametrize the lambda's type. It's just programmers who are prevented from creating instances by the lack of constructors.
As far as extensions go:
But can a compiler provide such constructor as an extension?
Yes. A compiler is allowed to provide this feature as an extension as long as all it does is make programs that would be ill-formed functional.
From [intro.compliance.general] - 4.1.1.8:
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this document. Having done so, however, they can compile and execute such programs.
However, for the feature at hand, MSVC would be having issues in its implementation as an extension:
- It should be emmiting a diagnostic.
- By its own documentation, it should refuse the code when using
/permissive-
. Yet it does not.
So it looks like MSVC is, either intentionally or not, behaving as if this was part of the language, which is not the case as far as I can tell.
QUESTION
In the answer to
it was shown that a program could have undefined behavior "depending on" (des Pudels Kern in this question) how an implementation used implementation leeway given by the standard. As an example, [expr.prim.lambda.closure]/2:
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [...] The closure type is not an aggregate type. An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:
- (2.1) the size and/or alignment of the closure type,
- (2.2) whether the closure type is trivially copyable ([class.prop]), or
- (2.3) whether the closure type is a standard-layout class ([class.prop]). [...]
It was pointed out in a comment to the answer that this scenario is not implementation-defined behavior
"implementation-defined" has a very specific meaning ([intro.abstract]/2); this isn't a case of that.
Would a program which had undefined behavior (UB) conditionally on such implementation leeway, have unconditional UB, possibly as per [intro.abstract]/5? Or how would such a program be described, in standardese terms?
...ANSWER
Answered 2021-Aug-19 at 16:33Assuming I understand the question correctly, here is a simpler example:
QUESTION
A colleague showed me a C++20 program where a closure object is virtually created using std::bit_cast
from the value that it captures:
ANSWER
Answered 2021-Aug-22 at 13:53But is the program well-formed according to the standard ...
The program has undefined behaviour conditional on leeway given to implementors. Particularly conditional on whether the closure type of the lambda
QUESTION
I want to check at compile time if std::span has a specific layout. The code below is what I've got so far. It doesn't work.
...ANSWER
Answered 2021-Jun-04 at 18:44Without reflection, there is no mechanism you can use to determine the layout of a type. You can test layout compatibility, but you cannot determine the layout itself. That is, if they're not layout compatible, you can't determine why they aren't.
Maybe that span
implementation puts the size first. Maybe the size is in a base class subobject which can be empty when the size is static. Who knows.
You cannot write code to bit_cast
a span
. Not code that works across implementations, anyway. And really, there's no point in doing so. You can just give your type the ability to construct itself from an existing span
. bit_cast
is returning a new object anyway, so it's not like it's going to be faster or something.
QUESTION
Violating strict-aliasing rules yields undefined behavior, e.g. when sending a struct over the network into a char buffer, and then that char pointer is C-style/std::reinterpret_cast()
casted to a struct pointer.
The C++ std::bit_cast()
function looks like it could be used to cast such pointers in an (implementation?) defined way, i.e. without violating strict-aliasing rules.
Example:
...ANSWER
Answered 2021-May-30 at 22:19Converting the pointer value is irrelevant. What matters is the object. You have a pointer to an object of type X, but the pointer's type is Y. Trying to access the object of type X through a pointer/reference to unrelated type Y is where the UB comes from.
How you obtained those pointers is mostly irrelevant. So bit_cast
is no better than reinterpret_cast
in this regard.
If there is no sockaddr_in
there, then you can't pretend that there is one. However, it's possible that implicit object creation in C++20 already solves this matter, depending on your code. If it does, then it still doesn't matter how you get the pointer.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install bit_cast
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page