Is there a way (trait or so) to detect, if struct/class has some padding?
I don't need cross-platform or standardized solution, I need it for MSVC2013.
I can check it like
namespace A
{
struct Foo
{
int a;
bool b;
};
}
#pragma pack(push, 1)
namespace B
{
struct Foo
{
int a;
bool b;
};
}
#pragma pack(pop)
static const bool has_padding = sizeof(A::Foo) != sizeof(B::Foo);
But C++ doesn't allow (as far as I know) generate this non-invasive (without touching existing structs)
Ideally I would like to get working something like this
template <typename T>
struct has_padding_impl
{
typedef __declspec(align(1)) struct T AllignedT;
};
template <typename T>
struct has_padding : typename std::conditional<sizeof(typename has_padding_impl<T>::AllignedT) == sizeof(T),
std::false_type,
std::true_type>::type{};
EDIT - Why do I need this?
I'am working with existing serialization system, which store some struct just taking void* to them (inside generic function) and store sizeof(T) number of bytes... Such binary file is not portable on platforms we are targeting, since different compilers are used, so there is no guarantee how is padding inserted. If I could statically detect all T which are structs with padding, I can force user to manually insert padding (some control padding e.g. not just random garbage) so there is no "random" padding. Another adventage is, when I diff two save files of same scenerio, they will look the same.
edit 2
the more I think about it, the more I realize I need cross-platform solution. We mainly develop on msvc2013 but our application is at final builded in msvc2012 and clang. But if I detected and get rid of all compiler-generated padding in msvc2013, there is no guarantee that other compiler doesn't insert padding... (so msvc2013 detection is not enough)
Do you need this information during run time?
Because if you want to know it in build time I believe you can use static_assert to get this information.
struct foo
{
uint64_t x;
uint8_t y;
};
#define EXPECTED_FOO_SIZE (sizeof(uint64_t) + sizeof(uint8_t))
static_assert(sizeof(foo) == EXPECTED_FOO_SIZE, "Using padding!");
If you need it during run time, you can try something like:
static const bool has_padding = (sizeof(foo) != EXPECTED_FOO_SIZE);
Also check this link from earlier post, maybe it will help.
Try out this macro :
#define TO_STR(str) #str
#define DECL_STRUCT_TEST_ALIGNED(structName, test_alignment, body) \
_Pragma(TO_STR(pack(push,test_alignment)))\
struct test_##structName \
body ; \
_Pragma(TO_STR(pack(pop))) \
struct structName \
body; \
static const bool has_padding_##structName = sizeof(test_##structName)!=sizeof(structName);
DECL_STRUCT_TEST_ALIGNED(bar, 1,
{
int a;
bool b;
}
)
DECL_STRUCT_TEST_ALIGNED(foo,1,
{
int a;
int b;
})
And now, at runtime you can test :
if (has_padding_foo)
{
printf("foo has padding\n");
} else {
printf("foo doesn't have padding\n");
}
if (has_padding_bar)
{
printf("bar has padding\n");
} else {
printf("bar has no padding\n");
}
And ofc, you can use static_assert if you want to get error at compile time.
May be you should try something like this:
#include <iostream>
using namespace std;
struct A
{
int a;
bool b;
};
int main(int argc, char *argv[])
{
A foo;
cout << "sizeof struct = " << sizeof(A) << endl;
cout << "sizeof items = " << sizeof(foo.a) + sizeof(foo.b) << endl;
return 0;
}
I got:
sizeof struct = 8
sizeof items = 5
I am on Ubuntu 14.04.
Related
I have a complicated structs that evolved from version to version, adding/removing fields. For backward compatibility, all the versions are kept in the code, leading to something like this :
struct MyDataV0{
int a;
.....
};
struct MyDataV1{
//int a disappeared for this version
double d; //this fields was added to this version
.....
};
I want to provide a unified view of this struct that is version agnostic. Is there a pattern or best practices to do this?
You can also take a closer look at creating a flexible container, for example, in C++ 17 you can use std::map with std::variant values.
Its definition is unified and version-agnostic.
#include <string>
#include <map>
#include <iostream>
#include <variant>
int main()
{
std::map<std::string, std::variant<int, double, std::string>> st;
st["version"] = 2;
st["field_int_v1"] = 1;
st["field_double_v2"] = 1.1; // added in version 2
st["field_string_v2"] = "1.1 in text";
//..
// process somewhere
std::cout << std::get<int>(st["field_int_v1"] ) << std::endl;
if (std::get<int>(st["version"]) == 2){
std::cout << std::get<double>(st["field_double_v2"] ) << std::endl;
std::cout << std::get<std::string>(st["field_string_v2"]) << std::endl;
}
return 0;
}
This may not provide a 'unified view', the typical approach to handling multiple versions is with namespacing:
namespace my_data
{
namespace v1
{
// v1
struct MyData { … };
}
inline namespace v2
{
// v2
struct MyData { … };
}
}
// To use v2
my_data::MyData data = {};
// or
my_data::v2::MyData data1 = {};
// To use v1
my_data::v1::MyData data2 = {};
By default, you will use the version of the struct which is in the inline namespace, if you want to reference an older (possibly deprecated) version, you will have to be explicit. You can then overload any function which consumes MyData, in the same namespace as the struct and rely on ADL to find the correct overload.
Using Extended Embedded Cpp. How can I make this result in a compilation error in a release build:
Param okParam("Yeah!"); // this line should be ok
Param nOkParam("REEEEEEEEEEE"); // too big array, not ok. compiler error.
where:
int const c_max = 10;
template<int N>
struct Param
{
char value[c_max];
Param(char const (&p_value)[N])
{
memcpy(value, p_value, sizeof(p_value));
}
};
I don't think you can template the constructor, so the entire struct needs to be templated, right?
I want this to provide a clean compiler error so that the person using this will notice it immediately.
Our version of extended embedded C++ doesn't provide any stl containers, I'm not sure if it's even possible.
I'm looking for some way to make the template result in a good compilation error. Sadly I can't use boost either, since the platform would not support it.
You have basically two solutions: SFINAE (C++98) or static_assert (C++11):
SFINAE
You can provide a constructor for Param only for char arrays less than a given size long. In C++98 this looks a bit ugly, but it works:
#include <cstddef>
template<bool b>
struct enable_if {};
template<>
struct enable_if<true>
{
typedef int type;
};
template<std::size_t MAXSIZE>
struct Param
{
template<std::size_t SIZE>
explicit Param(
char const (&input) [SIZE],
std::size_t = sizeof(typename enable_if<SIZE < MAXSIZE>::type) // SFINAE at work
) { (void) input; }
};
int main()
{
// "hello": char const[6], 6 < 7, OK
Param<7> p1("hello");
// "hello world": char const[12], 12 >= 7, KO
Param<7> p2("hello world"); // ugly error here
}
Live demo
Assert (C++11 only)
Inside the constructor of Param, you can check if the supplied char array is too big and pop a readable error at compilation-time:
#include <cstddef>
#include <type_traits>
template<std::size_t MAXSIZE>
struct Param
{
template<std::size_t SIZE>
explicit Param(char const (&input) [SIZE])
{ static_assert(sizeof(input) < MAXSIZE, "input is too big."); }
};
int main()
{
// "hello": char const[6], 6 < 7, OK
Param<7> p1("hello");
// "hello world": char const[12], 12 >= 7, KO
Param<7> p2("hello world"); // "error: static assertion failed: input is too big."
}
Live demo
Probably the simplest way is to add a static_assert, using one of the old C techniques for compile-time checks if your implementation doesn't have static_assert yet:
#include <cstring>
#if __cplusplus < 201103L
#define static_assert(expr, message) \
int static_assert_(int (&static_assert_failed)[(expr)?1:-1])
#endif
template<int N>
struct Param
{
static const int c_max = 10;
static_assert(N < c_max, "Param string too long");
char value[c_max];
Param(char const (&p_value)[N])
{
std::memcpy(value, p_value, sizeof p_value);
}
};
int main()
{
Param okParam("Yeah!"); // this line should be ok
Param nOkParam("REEEEEEEEEEE"); // too big array, not ok. compiler error.
}
I've been recently getting into template wizardry and in particular CRTP. I know that templates are used to make the compiler generate code for us so I was wondering if it were possible to make a template "decide" which parts of a function we would like it to include for a particular class. For example if I have the following code:
crtp.h
#include <iostream>
using std::endl;
using std::cout;
template<class T>
class A {
public:
void func() {
constexpr unsigned short mask = T::GetMask();
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
}
};
class B : public A<B> {
friend class A<B>;
protected:
static constexpr unsigned short GetMask() { return 0x0001; }
};
class C : public A<C> {
friend class A<C>;
protected:
static constexpr unsigned short GetMask() { return 0x0009; }
};
main.cpp
#include "ctrp.h"
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
using std::getchar;
using std::endl;
int main() {
B b;
C c;
cout << "B:" << endl;
b.func();
cout << endl << "C:" << endl;
c.func();
getchar();
}
Which when executed produces:
B:
Mask 1
C:
Mask 1
Mask 2
This works great, does exactly what I want it to. The problem is from my standpoint the if statements should be unnecessary. As I am dealing with constant expressions the compiler should have everything it needs to simply skip the branching and know to execute the first part for class B and both parts for class C.
I would like to cash in on this and specifically tell the compiler to remove the sections that are unnecessary for the particular class to avoid unnecessary branching at runtime. Unfortunately I have no idea how to do this, any ideas? Thanks in advance
Edit
In response to some of the awesome suggestions C++17's constexpr if expression is a near perfect solution that I had no idea existed, but am unfortunately unable to use. I am limited to using C++14.
If you care about performance, the compiler will very likely optimize out all "dead" branches and even the if condition, if it can evaluate it during compile time.
What is worse, all the branches need to be well formed until C++17 constexpr if. In this case, you can "outsource" the functionality to special (static member) functions and use specialization to invoke the right one. See #R Sahu's answer for the example.
Emulating if/else at compile time using template metaprogramming does not work that way. You have to imagine if/else using a different mindset.
Instead of
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
you'll have to use something along the lines of:
function1_selector<mask & 1>::dostuff();
function2_selector<mask & 1 << 3 >::dostuff();
where
template <bool> struct function1_selector
{
static void dostuff() { /* Do nothing */ }
};
template <> struct function1_selector<true> // Specialize for true
{
static void dostuff() { /* Do something useful */ }
};
Add code for function2_selector similarly.
In a bunch of code that I'm writing I want to indicate that certain variables are to be used in a certain way, or have a certain characteristic to them. For the sake of discussion, suppose variables can be sweet, salty, sour or bitter.
What I use now is something like:
int foo() {
int salty_x;
int sour_y;
do_stuff_with(salty_x,sour_y);
}
And I might also have sour_x, or salty_y etc.
Ideally - but this is not valid C++ - I would have been able to write something like this:
int foo() {
namespace salty { int x; }
namespace sour { int y; }
do_stuff_with(salty::x,sour::y);
}
and this would nicely allow for a "sour x" and a "salty x" in the same function - if this syntax had been valid of course.
This may remind you of Hungarian Notation, except that it's not about variable types or sizes, and that the saltiness or sourness etc. are not inherent in x or in y - they only describe the way they're used.
Now, you could ask: "Ok, why not just put these in struct's?", that is, why not do:
int foo() {
struct { int x; } salty;
struct { int y; } sour;
do_stuff_with(salty.x,sour.y);
}
But that preculdes defining additional salty/sour variables; and if I bunch them all at the beginning of the function, C-style, then it looks as though I indicate the variables are related, which is not necessarily the case.
What I currently do is just prefix the names: salty_x, sour_y. It's ugly but it works.
My question: Is there something else I could do which would look closer, in use, to my desired code, and at the same time not require too much "coding gymnastics"?
Due to popular demand: As a motivating/concretizing example, "salty" might mean "is uniform across all threads in a GPU warp, but possibly not across different warps" and "sour" might mean "is uniform across all threads in a CUDA kernel grid block / OpenCL workgroup when they reach this point in the code". But this is not a question about GPUs, CUDA, or OpenCL.
The hardest constraint was
Sometimes I even want to have a "sour x" and a "salty x" in the same
function
So - the solution is the first usage of variadic template template parameter I ever made - so, here you are:
template <typename T>
struct salty
{
T salty;
};
template <typename T>
struct sour
{
T sour;
};
template <typename T, template <typename> class ...D>
struct variable : D<T>...
{};
And the usage:
salty<int> x;
x.salty = 5;
variable<int, salty, sour> y;
y.sour = 6;
y.salty = 5;
I'm sure you've checked all conventional approaches and neither was satisfactory... Lets turn to the magic then to achieve (I think) exactly what you want (c++17 will be needed):
#include <iostream>
#include <type_traits>
#include <variant>
#include <utility>
#include <typeinfo>
#include <typeindex>
#include <map>
template <auto Label>
using ic = std::integral_constant<decltype(Label), Label>;
template <class... Ts>
struct context {
template <auto Label, auto (*Namespace)(std::integral_constant<decltype(Label), Label>)>
decltype(Namespace(ic<Label>{}))& get() {
try {
return std::get<decltype(Namespace(std::integral_constant<decltype(Label), Label>{}))>(values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)]);
} catch (std::bad_variant_access&) {
values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)] = decltype(Namespace(std::integral_constant<decltype(Label), Label>{})){};
}
return std::get<decltype(Namespace(std::integral_constant<decltype(Label), Label>{}))>(values[typeid(std::pair<std::integral_constant<decltype(Namespace), Namespace>, std::integral_constant<decltype(Label), Label>>)]);
}
std::map<std::type_index, std::variant<Ts...>> values;
};
int main(){
enum { x }; // defining label x
int salty(ic<x>); // x is an int in salty namespace
enum { y }; // defining label y
float sour(ic<y>); // y is a float in sour namespace
context<int, float, char> c;
c.get<x, salty>() = 2;
c.get<y, sour>() = 3.0f;
char sour(ic<x>); // x is a char in sour namespace
c.get<x, sour>() = 'a';
std::cout << "salty::x = " << c.get<x, salty>() << std::endl;
std::cout << "sour::y = " << c.get<y, sour>() << std::endl;
std::cout << "sour::x = " << c.get<x, sour>() << std::endl;
}
One thing to be mentioned - gcc doesn't like the code though according to standard it should: [see this] [and that].
If I understand your edit correctly, you want to be able to define variables that behave exactly like int or float variables, but retain additional, ideally compile-time, information about their types.
The only thing I can't help you with is this:
Sometimes I even want to have a "sour x" and a "salty x" in the same function, which I could do if this syntax had been valid.
Personally, I would just prefix the variable name.
Anyway, here is an example of what you can do.
enum class Flavor {
Salty, Sour
};
template <typename T, Flavor f>
struct Flavored {
using Type = T;
static constexpr Flavor flavor = f;
T value;
Flavored(T v) : value(v) {}
operator T() { return value; }
};
And here is an example of how to use it.
Postfixes.
They usually hamper readibility a lot less than prefixes, while maintaining the same hinting quality.
Yes I know it's obvious, but it's very possible that it hadn't come to your mind.
And mind that the Hungarian Notation was originally meant to be employed pretty much as you would in your case; see "Apps Hungarian" in that wikipedia entry.
When I make my own struct, say:
struct myStruct{
int data1;
int data2;
string data3;
}
I can initialize an instance of type myStruct like this:
myStruct instance1;
So my question is, why am I often seeing "struct" written during the initialization of a struct?
Maybe that's an inaccurate statement so here is an example of what I mean:
/*This is a tiny program that checks
to see if a file exists in
the current working directory. */
#include <sys/stat.h>
#include <iostream>
using namespace std;
const string FILENAME = data.txt;
int main(){
struct stat fileStatus; //<-- HERE HERE HERE!
if (FileExists(FILENAME, fileStatus)){
cout << "File Does Exist" << endl;
}else{
cout << "File Does NOT Exist" << endl;
}
return 0;
}
bool FileExists(const string & fileName,struct stat & fileStatus){
bool fileDoesNotExist = stat (fileName.c_str(), &fileStatus);
return !fileDoesNotExist;
}
>
LINE 13: struct stat fileStatus;
Is this something that was done in C for some reason?
Something with a macro or a typedef?
I just don't understand why this is the way it is.
This is a C thing; there's no good reason to continue to do it in C++.1
In C, struct is part of the typename, e.g.:
struct foo { int x; };
defines a type called struct foo. In C++, it defines a type called foo. In C, you can usually hide this irritation behind a typedef:
typedef struct foo { int x; } foo;
1 At least, not in code that couldn't possibly also be compiled as C (such as the example in your question).
You can do what you want by instead calling it like this:
typedef struct mystruct
{
int itema;
int itemb;
Etc...
}* mystruct;
So that's whenever you make a mystruct item it creates a pointer to your struct, else you have to call your struct by
struct mystruct *object;