Struct offsets differ? - c++

Normally I would have a good smile, but its so sneaky its not even funny.
How the hell can a struct differ from one file to another?
I had a struct like this:
typedef struct pp_sig_s
{
[...]
int flags;
size_t max;
bool is_reversed;
unsigned int sig[64];
size_t byref;
[...]
}
pp_sig_t;
It was defined in say "header01.h"
Some function I use is in "program01.cpp"
Declared this way
void PrintSig(pp_sig_t *s); // prints the content of sig[64] array in pp_sig_t for test purposes
Another object pp_sig_t called g_sig_1 was defined in "header02.cpp"...
This .cpp includes of course header01.h
I call the print routine this way inside it
PrintSig(&g_sig_1);
I notice the print result differs from the actual content.
Say sig contains 0xE8, then it printed 0xE800
Then, I thought, about 2 hours of investigation, it could be struct alignment.
I try it...
Declaring the struct this way in header01.h
#pragma push()
#pragma pack(4)
typedef struct pp_sig_s
{
[...]
int flags;
size_t max;
bool is_reversed;
unsigned int sig[64];
size_t byref;
[...]
}
pp_sig_t;
#pragma pop()
And suddenly everything works fine...
So basically its like if in program01.cpp the struct offsets were, i would guess, different than in program02.cpp...
How the hell can a struct differs from one file to another? How can we avoid this without using pragmas? Could it be called a compiler bug (i use Intel C++ XE Composer 2013 Update 2, on linux)?

It seems likely that this was caused by an alignment pragma that was in scope when one of the files included the header, but not when the other did.

Related

Templated typedef structs with constructor in C++

I have this code right now, which seems to work so far but I was wondering if there was a way to get the exact same struct in a more elegant way since my method so far needs a duplicate everytime for each struct... The end goal would be to have a typedefed struct which would swap the bytes according to the endianness automatically.
using ResourceHeader_t = struct ResourceHeader_s
{
uint32_t magic;
uint32_t chunkVersion;
uint32_t chunkSize;
};
template<bool bigEndian>
struct ResourceHeader : public ResourceHeader_s
{
ResourceHeader(ResourceHeader_t* ptr) : ResourceHeader_s(*ptr)
{
if (bigEndian)
{
LITTLE_BIG_SWAP(magic);
LITTLE_BIG_SWAP(chunkVersion);
LITTLE_BIG_SWAP(chunkSize);
}
}
};
Usage example :
ResourceHeader<true> resourceHeader((ResourceHeader_t *)fileBuffer);
There is no need for a typedef struct declaration in C++. This is a relic of C.
In C++, after declaring a struct ResourceHeader_s, or struct ResourceHeader_t, or just a plain struct ResourceHeader, the same symbol can be used directly by itself, without an explicit struct.
You might simply add the endianess as a ResourceHeader ctor parameter, rather than a template parameter. This would remove duplicate definitions of the struct (one for big and one not).

What's the modern C++ way to cast absolute addresses to pointer variables?

In the embedded world for ages people wrote hardware(-configuration)-register-mappings as structures, a really simple example for a 32-bit hardware:
#define hw_baseaddr ((uintptr_t) 0x10000000)
struct regs {
uint32_t reg1;
uint32_t reg2;
};
#define hw_reg ((volatile struct regs *) hw_baseaddr)
void f(void)
{
hw_reg->reg1 = 0xdeadcafe;
hw_reg->reg2 = 0xc0fefe;
}
This works very well, the compiler (gcc at least on our platform) recognizes that the hw_reg is referencing the same address (which is known and constant at compile-time) and is ld'ing it only once. The second st (store) is done with a 4-byte-offset with a single instruction - again on our platform.
How to reproduce this behavior with modern C++ (post C++11) without using #defines?
We tried a lot of things: static const inside and outside classes and constexpr. They both don't like (implicit) reinterprest_cast<>'s .
Responding to a comment as to why changing it: I'm afraid it's mostly fame and glory. But not only. With this C code debugging can be hard. Imagine you'd want to log all write-accesses, this approach would require you to rewrite everything everywhere. However, here I'm not looking for a solution which will simplify a specific situation, I'm looking for inspiration.
EDIT Just to clarify as per some comments: I'm asking this question not to change any code which is working (and was written in the 1990s). I'm looking for a solution for future projects, because I'm not totally happy with the define-implementation, and was asking myself whether modern C++ has a superior possibility.
I think variable templates make for an elegant solution here.
// Include this in some common header
template <class Impl>
volatile Impl& regs = *reinterpret_cast<volatile Impl*>(Impl::base_address);
template <std::uintptr_t BaseAddress>
struct HardwareAt {
static const std::uintptr_t base_address = BaseAddress;
// can't be instantiated
~HardwareAt() = delete;
};
// This goes in a certain HW module's header
struct MyHW : HardwareAt<0x10000000> {
std::uint32_t in;
std::uint32_t out;
};
// Example usage
int main()
{
std::printf("%p\n%p\n", &regs<MyHW>.in, &regs<MyHW>.out);
// or with alias for backward compatibility:
auto hw_reg = &regs<MyHW>;
std::printf("%p\n%p\n", &hw_reg->in, &hw_reg->out);
}
One benefit of using it like this instead of with macros, is that you're type safe, and you can actually refer to registers of different hardware modules from the same source file without mixing it all up.
Since the sole purpose of the #define is to give you access to struct members, you could use a template to do the equivalent. My compiler generates code for the template that is identical to the #define.
// #define hw_reg ((volatile struct regs *) hw_baseaddr)
template <class T, uintptr_t addr>
class RegsPtr
{
public:
RegsPtr() { ; }
volatile T* operator->() const { return reinterpret_cast<T*>(addr); }
volatile T& operator*() const { return *operator->(); }
};
const RegsPtr<struct regs, hw_baseaddr> hw_reg;

Writing a struct to flash memory

I am having problems writing a struct to flash memory using a microcontroller (cortex-M0 inside nrf58122 SoC). I don't know enough c/c++ to determine if it's a memory management issue or a fundamental lack of understanding of programming.
I have a class with a struct member:
struct settings_t
{
uint16_t n;
uint8_t b;
bool e;
} settings;
In one of my class methods, I need to write the contents of this struct to flash memory in the microcontroller (no EEPROM available). There are pre-written functions that I call in order to do this---I understand I need to erase a page before writing to it. If I try the following:
settings = {
constants::n,
constants::b,
constants::e
};
Where the values n, b, e are of the correct type, and I follow this definition by:
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &settings, sizeof(settings));
I get a runtime error (program execution halts, don't have an error code for it) when the flashWriteBlock function executes. However, if I copy the struct first:
settings_t cpy = settings;
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &cpy, sizeof(settings));
Then it does work. Can anyone shed some insight into this? I can provide more detail as needed.
The documentation may not say it, but the implementation shows that both the source and destination must be 32-bit aligned:
int flashWriteBlock( void *dst, const void *src, int cb )
{
uint32_t *d = dst;
const uint32_t *s = src;
/* The rest of the function snipped*/
}
The failure is due to the settings variable being 16-bit aligned. It will have to be forced to 32-bit alignment. How this is done is compiler dependent. The following example works for gcc:
struct settings_t
{
uint16_t n;
uint8_t b;
bool e;
} __attribute__ ((aligned (4))) settings;
If you are talking about an Arduino Uno and related ATMega based controllers you might want to consult the official Arduino Website: Reading and Writing Data Structures to EEPROM. The page contains templates for EEPROM_readAnything and EEPROM_writeAnything.

C++ Struct - Define Minimum Size

Is there a C++ (or MSVC) method of automatically padding a struct to a minimum size? For example, imagine the following pseudo-code:
#pragma pad(256) // bytes
struct SETUPDATA {
int var1;
double var2;
};
where sizeof(SETUPDATA) = 256 bytes
The goal here being, during development this struct's members can change without changing the footprint size at runtime.
You can use a union
struct SETUPDATA {
union { struct your_data; char [256]; }
}
or something like this. This ensures it's at least 256 but only as long as your_data is not larger.
You can also add a simple assert after that just does a compiler check assert(sizeof(struct SETUPDATA) == 256)
One way is to inherit from your "real" structure and use sizeof() to make up the padded structure, for example:
struct blah_real
{
int a;
};
struct blah : public blah_real
{
private:
char _pad[256 - sizeof(blah_real)];
};
You could use #ifdef DEBUG to only do this in the debug build and just use the real structure in release build.
The first thing you have ot ask yourself is why your application cares if the struct size changes. That indicate fragility to future changes and your design may be better served by instead allowing the application to seamlessly work in the face of struct size changes.
Perhaps you're trying to serialize the data directly and don't want to face changes in the format, but in that case you're already tying yourself to one specific representation of the structure in memory. For example support the size of one of the builtin-type members changes due to a compiler upgrade or options.
But let's say you really do want to do this.
Just wrap the data in an impl and pad the real struct:
struct SetupData
{
struct Impl
{
int var1;
double var2;
};
Impl impl_;
unsigned char pad_[256 - sizeof(Impl)];
};

Preventing linker from excluding unreferenced static

I have the need to store compile time type information (name, fields...) inside a list that i can iterate through at run time.
I've come up with something that looks like this:
#include <stdio.h>
struct Type
{
const char *m_szName;
Type *m_pNext;
};
struct TypeList
{
static Type *ms_pHead;
static Type *Push(Type *pHead)
{
Type *pNext(ms_pHead);
ms_pHead = pHead;
return pNext;
}
};
Type *TypeList::ms_pHead = 0;
template <typename T>
struct TypeHolder
{
static Type ms_kType;
};
#define _DECLARE_TYPE(_Name) \
template <> Type TypeHolder<_Name>::ms_kType = {#_Name, TypeList::Push(&ms_kType)};
struct A
{
float m_fField;
};
_DECLARE_TYPE(unsigned int);
_DECLARE_TYPE(float);
_DECLARE_TYPE(A);
int main()
{
Type *pType(TypeList::ms_pHead);
while (pType != 0)
{
printf("%s\n", pType->m_szName);
pType = pType->m_pNext;
}
return 0;
}
This way all i need to do to declare a new type and register it statically at the same time is use the macro _DECLARE_TYPE anywhere in my code.
The above example would output:
A
float
unsigned int
On MSVC9 everything works fine and i get output until i turn optimizations on, which include "Eliminate Unreferenced Data (/OPT:REF)".
If i do that, the program above has no output.
Now i see that TypeHolder, TypeHolder, TypeHolder are not referenced directly in the code, so i imagine that the linker is removing them regardless of any side effects their initialization might have.
The reason why i used static initialization is that it allows me to declare and register a type anywhere in my code without having to create a big function that i manually call that would do
TypeList::Push(TypeHolder<unsigned int>::ms_kType);
TypeList::Push(TypeHolder<float>::ms_kType);
TypeList::Push(TypeHolder<A>::ms_kType);
for each type.
Also, i would like my solution to work on a wide range of compilers, so using non-standard #pragma directives that only work on MSVC or even turning optimizations off is not an option.
Is there any way for me to avoid the hassle of having to manually list all the types in a separate place (other than inside the macro)?