What about std::array storage placement? - c++

I want to have mechanism that allows me to concatenate variadic function parameters (all of them are convertable into value of some specific plain-old-data type F) into a raw data storage of appropriate size (size is greater than or equal to sum of parameters sizes). I wrote the following code:
#include <iostream>
#include <iterator>
#include <new>
#include <cstdlib>
#include <cassert>
#include <array>
#include <tuple>
template< typename F >
struct repacker
{
constexpr
repacker(F * const _storage)
: storage_(_storage)
{
static_assert(std::is_pod< F >::value, "Underlying type is not a POD type.");
}
F * const storage_;
template< typename... P >
auto operator () (P && ...params) const
{
constexpr auto N = sizeof...(P);
using A = std::array< F, N >; // using A = F [N]; this eliminates the problem
static_assert(sizeof(A) == sizeof(F) * N, "This compiler does not guarantee, that this code to be working.");
#ifndef _NDEBUG
auto a =
#else
std::ignore =
#endif
new (storage_) A{F(params)...};
assert(static_cast< void * >(a) == static_cast< void * >(a->data()));
return N;
}
};
int main()
{
using F = double;
constexpr auto N = 6;
F * a = new F[N];
{
F x(1.0);
F const y(2.0);
repacker< F > r(a);
auto const M = r(x, y, 3.0, 4, 5.0f, 6.0L);
assert(M == N);
}
std::copy(a, a + N, std::ostream_iterator< F const & >(std::cout, " "));
std::cout << std::endl;
delete [] a;
return EXIT_SUCCESS;
}
But I am not sure that the assert(static_cast< void * >(&a) == static_cast< void * >(a.data())); assertion is true for all the compilers. This is a necessary condition for a code to be working.
Is it always the assertion is true?

This is a necessary condition for a code to be working.
No, it is not. OK, it is necessary, but it is not sufficient. Another necessary condition for this (very terrible) code to be working is:
sizeof(std::array<F, N>) == sizeof(F) * N;
And that is not guaranteed by the standard. std::array is not layout-compatible with C-style arrays. The contents of std::array are, but not the full type itself.
If you want to initialize some object in memory you allocate in blocks of bits, you should new up a char[] array, not an array of F. You should allocate this:
char *a = new char[sizeof(std::array<F, N>)];

#AndyProwl pointed out something very important:
std::array is guaranteed to be an aggregate as defined by C++11 8.5.1/1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equalinitializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
Let us test that against C++11 9/7:
A standard-layout class is a class that:
has no non-static data members of type non-standard-layout class (or array of such types) or reference
[...]
Violationg this is easier than one might expect:
struct violator { virtual ~violator () { } };
typedef ::std::array<violator, 2> violated;
Here the type violated would have a data member that is of type array of a non-standard-layout class.
Therefore the guarantee expressed in C++11 9.2/20 (that allows reinterpreting a pointer to the class as one to its first member, and is as far as I can see the only passage in the standard that might make your assumption valid) does not hold in all cases for ::std::array.

Standard layout types guarantee that you can convert a pointer to them to a pointer of their first member using reinterpret_cast. IIRC reinterpret_cast can potentially return a different address than used as input (due to alignment restriction).

Related

casting structure pointer to union pointer in C++

I have a Union containing various struct member.
union U {
struct S1 as_s1;
struct S2 as_s2;
…
};
How can I cast pointer to struct as_s1 to a pointer to union U in C++?
I know because of this that it can be easily done using C casting. But I want to use the feature of Advance class type casting of C++ without causing any errors.
From the standard 6.9.2.4.
Two objects a and b are pointer-interconvertible if:
they are the same object, or
one is a standard-layout union object and the other is a non-static data member of that object (12.3),
one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object (12.2), or
there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (8.2.10).
This means that you can convert them to each other using reinterpret_cast. However, you cannot access the memory of wrong type. E.g., following is a well-defined code:
#include <iostream>
struct S1 {
int i;
};
struct S2 {
short int i;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
void printUnion(U* u, int type) {
if (type == 0){
S1 *s1 = reinterpret_cast<S1*>(u);
std::cout << s1->i << std::endl;
} else {
S2 *s2 = reinterpret_cast<S2*>(u);
std::cout << s2->i << std::endl;
}
}
int main() {
S1 s1{1};
printData(reinterpret_cast<U*>(&s1), 0);
S2 s2{2};
printData(reinterpret_cast<U*>(&s2), 1);
}
But, if you give a wrong type parameter to the printData-function, the behavior is undefined.
In c++ it is hard to imagine a program with a good design where the cast would be needed. In c if you already have a need for a union object there might be a case where this could be used to implement polymorphism (of course no reinterpret_cast there). Though it is usually done with void*.
The proper casting for such pointer casts is reinterpret_cast:
#include <stdio.h>
struct S1 {
int x,y;
};
struct S2 {
double a,b;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
int main() {
struct S1 mys1;
union U *uptr = reinterpret_cast<union U*>(&mys1);
uptr->as_s1.x = 42;
printf("%d\n",mys1.x);
return 0;
}
Beware that since sizeof(struct S1) < sizeof(struct S2), in this example, and you only allocated enough memory for the size of S1, if you try to do anything on uptr->as_s1.b you will corrupt the stack.

Get pointer to object from pointer to some member

Suppose there's a structure
struct Thing {
int a;
bool b;
};
and I get a pointer to member b of that structure, say as parameter of some function:
void some_function (bool * ptr) {
Thing * thing = /* ?? */;
}
How do I get a pointer to the containing object? Most importantly: Without violating some rule in the standard, that is I want standard defined behaviour, not undefined nor implementation defined behaviour.
As side note: I know that this circumvents type safety.
If you are sure that the pointer is really pointing to the member b in the structure, like if someone did
Thing t;
some_function(&t.b);
Then you should be able to use the offsetof macro to get a pointer to the structure:
std::size_t offset = offsetof(Thing, b);
Thing* thing = reinterpret_cast<Thing*>(reinterpret_cast<char*>(ptr) - offset);
Note that if the pointer ptr doesn't actually point to the Thing::b member, then the above code will lead to undefined behavior if you use the pointer thing.
void some_function (bool * ptr) {
Thing * thing = (Thing*)(((char*)ptr) - offsetof(Thing,b));
}
I think there is no UB.
X* get_ptr(bool* b){
static typename std::aligned_storage<sizeof(X),alignof(X)>::type buffer;
X* p=static_cast<X*>(static_cast<void*>(&buffer));
ptrdiff_t const offset=static_cast<char*>(static_cast<void*>(&p->b))-static_cast<char*>(static_cast<void*>(&buffer));
return static_cast<X*>(static_cast<void*>(static_cast<char*>(static_cast<void*>(b))-offset));
}
First, we create some static storage that could hold an X. Then we get the address of the X object that could exist in the buffer, and the address of the b element of that object.
Casting back to char*, we can thus get the offset of the bool within the buffer, which we can then use to adjust a pointer to a real bool back to a pointer to the containing X.
My proposal is derived from the #Rod answer in Offset from member pointer without temporary instance, and the similar #0xbadf00d's one in Offset of pointer to member.
I started imagining a form of offset driving the implementation of a pointer to a class data member, later confirmed by the post in question and the tests i've made.
I'm not a C++ practitioner so sorry for the brevity.
#include <iostream>
#include <cstddef>
using namespace std;
struct Thing {
int a;
bool b;
};
template<class T, typename U>
std::ptrdiff_t member_offset(U T::* mem)
{
return
( &reinterpret_cast<const char&>(
reinterpret_cast<const T*>( 1 )->*mem )
- reinterpret_cast<const char*>( 1 ) );
}
template<class T, typename U>
T* get_T_from_data_member_pointer (U * ptr, U T::*pU) {
return reinterpret_cast<T*> (
reinterpret_cast<char*>(ptr)
- member_offset(pU));
}
int main()
{
Thing thing;
thing.b = false;
bool * ptr = &thing.b;
bool Thing::*pb = &Thing::b;
std::cout << "Thing object address accessed from Thing test object lvalue; value is: "
<< &thing << "!\n";
std::cout << "Thing object address derived from pointer to class member; value is: "
<< get_T_from_data_member_pointer(ptr, &Thing::b) << "!\n";
}

How can I efficiently clone a dynamically allocated array?

I have a class which is a templated smart pointer meant for wrapping dynamically allocated arrays. I know that there are classes in the STL that can be used for this, especially in C++11, but this is a widely-used internal class.
I wish to write a Clone() method for it. My initial implementation used std::copy, but I realized I should be able to avoid the default construction when allocating the array.
My attempt at a PoC ends up with a segmentation fault:
#include <iostream>
#include <algorithm>
class A
{
public:
A(int j) : i(j) {}
~A() {std::cout << "Destroying " << i << std::endl;}
private:
int i;
};
int main()
{
int a[] = {1, 2, 3};
A* arr = static_cast<A*>(::operator new[](sizeof(A) * 3));
std::uninitialized_copy(a, a + 3, arr);
delete [] arr;//::operator delete[](arr);
}
How do I create a dynamically allocated array of T, initialized with std::uninitialized_copy, so that it can be deleted with 'delete []' (i.e. treated as if it was allocated with a simple 'new T[N]')?
Since it seems people have had trouble understanding what I'm asking, here's the essence of my question:
#include <algorithm>
template <typename T>
T* CloneArray(T* in_array, size_t in_count)
{
if (!in_array)
return nullptr;
T* copy = new T[in_count];
try
{
std::copy(in_array, in_array + in_count, copy);
}
catch (...)
{
delete [] copy;
throw;
}
return copy;
}
How would I rewrite this function in a way that prevents T::T() from being called (if it even exists!), while returning the exact same result (let's assume our types are well behaved in that T t; t = other; and T t(other); are equivalent), including the fact that the result of the function can be deleted using the standard delete [] operator.
How do I create a dynamically allocated array of T, initialized with std::uninitialized_copy, so that it can be deleted with 'delete []' (i.e. treated as if it was allocated with a simple 'new T[N]')?
So, given the relatively simple requirement that the memory be able to be deleted with delete[], lets see what options we have.
Note: All quotes from the standard are from the C++14 draft N3797 and I'm not the best at standard-interpreting so take this with a grain of salt.
Mixing malloc()/free() and new[]/delete[]
Undefined, since new doesn't necessarily call malloc, see §18.6.1/4 (default behavior of operator new):
Default behavior:
Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified.
Avoiding default-initialization
So, seeing that we're required to use new[] if we want to use delete[],
looking at the standard for information about initialization in a new-expression §5.3.4/17:
A new-expression that creates an object of type T initializes that object as follows:
If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed, the object has indeterminate value.
Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct-initialization.
and going to §8.5/7:
To default-initialize an object of type T means:
if T is a (possibly cv-qualified) class type (Clause 9), the default constructor (12.1) for T is called (and the initialization is ill-formed if T has no default constructor or overload resolution (13.3) results in an ambiguity or in a function that is deleted or inaccessible from the context of the initialization);
if T is an array type, each element is default-initialized;
we see that if we omit a new-initializer in our new[], all the elements of the array will be default initialized via their default constructors.
So, what if we include a new-initializer, do we have any options? Going back to its definition in §5.3.2/1:
new-initializer:
(expression-list opt)
braced-init-list
The only possibility we are left with is a braced-init-list (expression-list is for non-array new-expressions). I managed to get it working for objects with compile time size, but obviously that's not terribly helpful. For reference (portions of code adapted from here):
#include <iostream>
#include <utility>
struct A
{
int id;
A(int i) : id(i) {
std::cout << "c[" << id << "]\t";}
A() : A(0) {}
~A() {std::cout << "d[" << id << "]\t";}
};
template<class T, std::size_t ...I>
T* template_copy_impl(T* a, std::index_sequence<I...>) {
return new T[sizeof...(I)]{std::move(a[I])...};
}
template<class T, std::size_t N,
typename Indices = std::make_index_sequence<N>>
T* template_copy(T* a) {
return template_copy_impl<T>(a, Indices());
}
int main()
{
const std::size_t N = 3;
A* orig = new A[N];
std::cout << std::endl;
// modify original so we can see whats going on
for (int i = 0; i < N; ++i)
orig[i].id = 1 + i;
A* copy = template_copy<A, N>(orig);
for (int i = 0; i < N; ++i)
copy[i].id *= 10;
delete[] orig;
std::cout << std::endl;
delete[] copy;
std::cout << std::endl;
}
Which when compiled with -std=c++1y (or equivalent) should output something like:
c[0] c[0] c[0]
d[3] d[2] d[1]
d[30] d[20] d[10]
Different types in new[] vs delete[]
To summarize, not only are we required to use new[] if we want to use delete[] but when omitting a new-initializer, our objects are default-initialized. So, what if we allocate memory using a fundamental type (similar, in a way, to using placement new), it will leave the memory uninitialized, right? Yes, but its undefined to delete the memory with something like T* ptr = /* whatever */; delete[] ptr if it was allocated with a different type. See §5.3.5/2:
In the second alternative (delete array), the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression. If not, the behavior is undefined. [ Note: this means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new-expression. — end note ]
and §5.3.5/3, which hints at the same thing:
In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
Other options?
Well, you could still use unique_ptrs as others have suggested. Although given that you're stuck with a large code base it's probably not feasible. Again for reference, here's what my humble implementation might look like:
#include <iostream>
#include <memory>
struct A
{
int id;
A(int i) : id(i) {
std::cout << "c[" << id << "]\t";}
A() : A(0) {}
~A() {std::cout << "d[" << id << "]\t";}
};
template<class T>
struct deleter
{
const bool wrapped;
std::size_t size;
deleter() :
wrapped(true), size(0) {}
explicit deleter(std::size_t uninit_mem_size) :
wrapped(false), size(uninit_mem_size) {}
void operator()(T* ptr)
{
if (wrapped)
delete[] ptr;
else if (ptr)
{
// backwards to emulate destruction order in
// normally allocated arrays
for (std::size_t i = size; i > 0; --i)
ptr[i - 1].~T();
std::return_temporary_buffer<T>(ptr);
}
}
};
// to make it easier on ourselves
template<class T>
using unique_wrap = std::unique_ptr<T[], deleter<T>>;
template<class T>
unique_wrap<T> wrap_buffer(T* orig)
{
return unique_wrap<T>(orig);
}
template<class T>
unique_wrap<T> copy_buffer(T* orig, std::size_t orig_size)
{
// get uninitialized memory
auto mem_pair = std::get_temporary_buffer<T>(orig_size);
// get_temporary_buffer can return less than what we ask for
if (mem_pair.second < orig_size)
{
std::return_temporary_buffer(mem_pair.first);
throw std::bad_alloc();
}
// create a unique ptr with ownership of our memory, making sure to pass
// the size of the uninitialized memory to the deleter
unique_wrap<T> a_copy(mem_pair.first, deleter<T>(orig_size));
// perform the actual copy and return the unique_ptr
std::uninitialized_copy_n(orig, orig_size, a_copy.get());
return a_copy;
}
int main()
{
const std::size_t N = 3;
A* orig = new A[N];
std::cout << std::endl;
// modify original so we can see whats going on
for (int i = 0; i < N; ++i)
orig[i].id = 1 + i;
unique_wrap<A> orig_wrap = wrap_buffer(orig);
{
unique_wrap<A> copy = copy_buffer(orig, N);
for (int i = 0; i < N; ++i)
copy[i].id *= 10;
// if we are passing the original back we can just release it
A* back_to_somewhere = orig_wrap.release();
delete[] back_to_somewhere;
std::cout << std::endl;
}
std::cout << std::endl;
}
Which should output:
c[0] c[0] c[0]
d[3] d[2] d[1]
d[30] d[20] d[10]
Lastly, you might be able to override the global or class operator new/delete, but I wouldn't suggest it.
Since A already is a smart pointer to a class that wraps dynamically allocated memory, it's guaranteed that the memory will not be deallocated until all references are released. Thus you can use a simple array or vector and copy the smart pointers around, no need to dynamically allocate the array.
For example:
typedef sdt::vector<A<SomeType> > AVector;
AVector copy(AVector in)
{
AVector copyArray = in;
return copyArray;
}

Anonymous union and struct [duplicate]

This question already has answers here:
Why does C++ disallow anonymous structs?
(7 answers)
Closed 8 years ago.
How would you go about doing this in standard C++11/14 ? Because if I'm not mistaken this isn't standard compliant code with the anonymous structs.
I wish to access the members the same way as you would with this.
template <typename some_type>
struct vec
{
union {
struct { some_type x, y, z; };
struct { some_type r, g, b; };
some_type elements[3];
};
};
Yes, neither C++11 nor C++14 allow anonymous structs. This answer contains some reasoning why this is the case. You need to name the structs, and they also cannot be defined within the anonymous union.
§9.5/5 [class.union]
... The member-specification of an anonymous union shall only define non-static data members. [ Note: Nested types, anonymous unions, and functions cannot be declared within an anonymous union. —end note ]
So move the struct definitions outside of the union.
template <typename some_type>
struct vec
{
struct xyz { some_type x, y, z; };
struct rgb { some_type r, g, b; };
union {
xyz a;
rgb b;
some_type elements[3];
};
};
Now, we require some_type to be standard-layout because that makes all the members of the anonymous union layout compatible. Here are the requirements for a standard layout type. These are described in section §9/7 of the standard.
Then, from §9.2 [class.mem]
16 Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9).
18 If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.
And for the array member, from §3.9/9 [basic.types]
... Scalar types, standard-layout class types (Clause 9), arrays of such types
and cv-qualified versions of these types (3.9.3) are collectively called standard-layout types.
To ensure that some_type is standard layout, add the following within the definition of vec
static_assert(std::is_standard_layout<some_type>::value, "not standard layout");
std::is_standard_layout is defined in the type_traits header. Now all 3 members of your union are standard layout, the two structs and the array are layout compatible, and so the 3 union members share a common initial sequence, which allows you to write and then inspect (read) any members belonging to the common initial sequence (the entire thing in your case).
Anonymous unions are allowed in C++11/14. See the example of their usage at Bjarne Stroustrup's C++11 FAQ
Regarding anonymous structs see Why does C++11 not support anonymous structs, while C11 does? and Why does C++ disallow anonymous structs and unions?
Though most compilers support anonymous structs, if you want your code to be standard compliant you have to write something like this:
template <typename some_type>
struct vec
{
union {
struct { some_type x, y, z; } s1;
struct { some_type r, g, b; } s2;
some_type elements[3];
};
};
I think the other answers sort of missed the point of the question:
I wish to access the members the same way as you would with this.
In other words, the question is really "how do I define a type vec in a standard-compliant manner such that given an object u of that type, u.x, u.r, and u.elements[0] all refer to the same thing?"
Well, if you insist on that syntax...then the obvious answer is: references.
So:
template <typename some_type>
struct vec
{
vec() = default;
vec(const vec& other) : elements{ other.elements[0], other.elements[1], other.elements[2] } {}
vec & operator=(const vec &other) {
elements[0] = other.elements[0];
elements[1] = other.elements[1];
elements[2] = other.elements[2];
return *this;
}
some_type elements[3];
some_type &x = elements[0], &y = elements[1], &z = elements[2];
some_type &r = elements[0], &g = elements[1], &b = elements[2];
};
The first problem with this approach is that you need extra space for 6 reference members - which is rather expensive for such a small struct.
The second problem with this approach is that given const vec<double> v;, v.x is still of type double &, so you could write v.x = 20; and have it compile without warning or error - only to get undefined behavior. Pretty bad.
So, in the alternative, you might consider using accessor functions:
template <typename some_type>
struct vec
{
some_type elements[3];
some_type &x() { return elements[0]; }
const some_type &x() const { return elements[0]; }
some_type &y() { return elements[1]; }
const some_type &y() const { return elements[1]; }
some_type &z() { return elements[2]; }
const some_type &z() const { return elements[2]; }
some_type &r() { return elements[0]; }
const some_type &r() const { return elements[0]; }
some_type &g() { return elements[1]; }
const some_type &g() const { return elements[1]; }
some_type &b() { return elements[2]; }
const some_type &b() const { return elements[2]; }
};
You would have to write u.x() etc. instead of u.x, but the space savings is considerable, you can also rely on the compiler-generated special member functions, it's trivially copyable if some_type is (which enables some optimizations), it's an aggregate and so can use the aggregate initialization syntax, and it's also const-correct.
Demo. Note that sizeof(vec<double>) is 72 for the first version and only 24 for the second.

Auto + static in-class constant initalization with meta-programming

Consider the following simplified template meta-programming code that implements an Angle class that is internally storing the modulo 360 degrees reduced value.
#include <iostream>
#include <typeinfo>
template<int N, int D>
struct Modulus
{
static auto const value = N % D;
};
template<int N>
struct Angle
{
static auto const value = Modulus<N, 360>::value; // ERROR
//static int const value = Modulus<N, 360>::value; // OK
//static auto const value = N % 360; // OK
typedef Angle<value> type;
};
int main()
{
std::cout << typeid(Angle<30>::type).name() << "\n";
std::cout << typeid(Angle<390>::type).name() << "\n";
return 0;
}
Output on Ideone
With Visual C++ 2010 Express, I can do static auto const = Modulus<N, 360>::value, but with MinGW gcc 4.7.2 (Nuwen distro) or Ideone (gcc 4.5.1) I have to either explicitly denote the type as static int const value = Modulus<N, 360>::value or I have to use auto with the full modular expression as static auto const value = N % 360;.
Question: Which compiler is correct acccording to the new C++11 Standard?
The code is valid. Visual C++ is right to accept it and gcc is wrong to reject it (for completeness, Clang 3.1 also accepts the code). The specification states that (C++11 7.1.6.4[dcl.spec.auto]/4):
The auto type-specifier can also be used...in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition.
Your value is a static data member. It has a brace-or-equal-initializer (that is the = Modulus<N, 360>::value part of the declaration), and the initializer appears within the member-specification of the class definition (i.e., it's what mortals might call an "inline initializer").