I'm trying to directly cast a stream of data into a structure that actually has a variable number of other structures as members. Here's an example:
struct player
{
double lastTimePlayed;
double timeJoined;
};
struct team
{
uint32_t numberOfPlayers;
player everyone[];
};
then I call:
team *myTeam = (cache_team*)get_stream();
This should work like some kind of serialization, I know my stream is structured exactly as represented above, but I have the problem of the numberOfPlayers being a variable.
My stream starts with 4 bytes representing the number of players of the team, then it contains each player (in this case, each player has only lastTimePlayed and timeJoined).
The code posted seems to be working, I still get a warning from the compiler because of the default assignment and copy constructors, but my question is it it's possible to do this some other way, a better way.
BTW, my stream is actually a direct mapping to a file, and my goal is to use the structure as if it was the file itself (that part is working properly).
uint32_t is 4 bytes. If it starts with 8 bytes you want a uint64_t.
If you want to get rid of the warning you can make the default copy and assignment private:
struct team {
// ...
private:
team(const team &);
team &operator=(const team &);
};
Since you'd probably want to pass everything by pointer anyways it'll prevent ever doing an accidental copy.
Casting the mapped pointer to the struct is probably the easiest way. The big thing is to just make sure everything is lining up correctly.
Visual Studio 2012 gives the following:
warning C4200: nonstandard extension used : zero-sized array in struct/union
A structure or union contains an array with zero size.
Level-2 warning when compiling a C++ file and a Level-4 warning when compiling a C file.
This seems to be a legitimate message. I would recommend you to modify your struct to:
struct team
{
uint32_t numberOfPlayers;
player everyone[1];
};
Such definition is less elegant, but the result will be basically the same. C++ is not checking the value of indexes. Tons of code are using this.
New development should avoid the "array size violations" where possible. Describing external structures in this way is acceptable.
Both scaryrawr's solution, and yours do the trick, but I was in fact searching for another way.
I in fact did find it. I used an uint32_t everyonePtr instead of the array, then I will convert the uint32_t to a pointer using a reinterpret_cast like this:
player *entries = reinterpret_cast<player*>(&team->everyonePtr);
then my mapping will work as expected, and I think it's easier to understand than the array[1] or even the empty one. Thank you guys.
Related
Good evening!
I'm writing an Arduino library. Inside it, I want to instantiate an object from another library whose constructor needs to be passed a parameter, but I don't want to hard-code such parameter. I need some guidance about how to do this.
Here's the relevant part of my code so far:
HSBC_CAN.h:
class HSBC_CAN {
public:
HSBC_CAN(uint8_t, uint8_t);
private:
uint8_t _int_pin;
};
HSBC_CAN.cpp:
#include <HSBC_CAN.h>
#include <mcp_can.h>
extern MCP_CAN *canbus_esc;
HSBC_CAN::HSBC_CAN(uint8_t int_pin, uint8_t cs_pin) {
_int_pin = int_pin;
canbus_esc = new MCP_CAN(cs_pin);
}
To be clear, the way to instantiate an object from MCP_CAN class is MCP_CAN foo(int bar), where bar is the chip select pin number for SPI protocol. I want my library to instantiate an object of MCP_CAN class but I need to be able to pass the chip select pin number when instantiating an object from my new class HSBC_CAN. This is the error I get with the above code:
error: request for member 'begin' in 'canbus_esc', which is of pointer type 'MCP_CAN*' (maybe you meant to use '->' ?)
Probably the way I did in my sample code is totally wrong (with the extern keyword and the new operator) but that's just what came out from my mind ATM.
Thanks for the time.
The error message from the compiler is very useful and if you would follow its advice of replacing . with -> it would probably fix your immediate problem. Since canbus_esc is a pointer, you must dereference it before accessing its members or functions. So if it has a function named begin that can be called with zero arguments, you might write:
canbus_esc->begin();
That line is equivalent to:
(*canbus_esc).begin();
Also, get rid of the word extern on the line that defined canbus_esc, or else you will get an undefined reference error for it.
However, I have two issues with the code you have presented: First of all, you are using new, which does dynamic memory allocation. It's a good idea to avoid dynamic memory allocation on small devices like AVRs if you can, since you never know if those allocations are going to fail until you actually run the program (you might be using up too much memory in other parts of your program). Secondly, you defined your canbus_esc at the file scope, so there can only be one of them. This means you can't really create multiple HSBC_CAN objects; the second one will overwrite the canbus_esc create by the first. Although that might be fine for your application, it seems like a needless limitation.
I'd suggest writing your code like this instead:
Header file:
#include <mcp_can.h>
class HSBC_CAN {
public:
HSBC_CAN(uint8_t int_pin, uint8_t cs_pin);
void begin();
private:
uint8_t _int_pin;
MCP_CAN can;
};
Source file:
#include <HSBC_CAN.h>
HSBC_CAN::HSBC_CAN(uint8_t int_pin, uint8_t cs_pin)
: can(cs_pin) // This line constructs the MCP_CAN object
{
_int_pin = int_pin;
}
HSBC_CAN::begin()
{
can.begin(42, 42, 42); // TODO: fix arguments
}
Another idea, which might be better, would be for you to have your HSBC_CAN object take a pointer to an MBC_CAN object and store the pointer as a member variable in the HSBC_CAN class. That option would make a lot of sense if there are multiple devices on the CAN bus that you want to talk to using that MBC_CAN object. You could have multiple classes using a single MBC_CAN object via pointers.
OS : xp
IDE : VS 2008
In the project that i'm doing in visual C++ i have declared a std::vector inside managed class as so
std::vector<pts> dataPoints;//this gives error c4368 : mixed type not allowed
but this works
std::vector<pts> * dataPoints;//a pointer to the vector
i then have created this vector on the free store as so in the constructor of the managed class
dataPoints = new std::vector<pts>(noOfElements,pts());//which is not so attractive.
the reason i need vector is because there is file that i'm reading through the ifstream and storing those values in the vector.
Q1) why is that i'm able to declare a pointer to object of native type(i guess)but not an object?
furthermore, prior to trying vector i tried the managed array as so
cli::array<Point> dataPoints //and i defined it later.
but when i do this
ifile >> dataPoints[i].X;
it gives an error c2678 : operator= is not overloaded for int!!.
Q2) why is it that i cant use a managed code here. At first i thought it might be a wrapper class Int but then autounboxing(conversion operators) should take care of it?or is it that Point::X is qualified with property and thus is not recognized as normal int? what am i missing?.
this is the reason i went for vector and pts solution.
pts is as follows
struct pts
{
int X, int Y;
pts() : X(0),Y(0){}
pts(int x,int y) : X(x),Y(y){}
};//this i created to store the data from the file.
An important property of managed class objects is that they get moved by the garbage collector. This happens when it compacts the heap. That plays havoc with native C++ objects, pointers to their members will become invalid. So as a rule, the compiler forbids embedding a native non-POD object inside a managed one. A pointer is not a problem.
The exact same problem exists for your use of the >> operator. The int gets passed by reference to operator>>(). Disaster strikes if the garbage collector kicks in right between the code taking the reference of the int and calling the operator. A simple workaround for that one is an intermediate step through a local variable:
int x;
ifile >> x;
dataPoint[i].X = x;
Which works because local variables are stable and are not subject to garbage collection.
None of this is a problem in native code. Do keep in mind that your ref class can easily call a native function. So separating the two can be useful and/or necessary.
You can't directly contain a native type within a managed type: this is just a restriction on C++/CLI. I'm thinking this might be to do with the possibilities of pointers within the native type. If the native type is directly within the managed type, then when managed objects get shuffled around during garbage collection, then these pointers would point to the original, now incorrect, memory.
Therefore the native object needs to be on the heap, so that its internals don't get changed by garbage collection. So you need to hold the vector as a pointer, and delete it appropriately. Note that the latter isn't entirely trivial, and you need to have some knowledge of C++/CLI (which differs subtly from C#). See http://msdn.microsoft.com/en-us/library/ms177197(v=vs.100).aspx.
Looking at the last time I did this, in my file I had
public:
!NetClass();
~NetClass() { this->!NetClass(); } // avoid arning C4461
private:
class NativeImpl* const m_pImpl; // can't contain NativeImpldirectly
And in the cpp file I had
NetClass::!NetClass()
{
// implement finalizer in ref class
delete m_pImpl;
}
You might just want to use the pimpl idiom here if you have more than one native class to contain. See Why should the "PIMPL" idiom be used?.
Finally, I last did this quite a while ago, and I'm just saying what worked for me at the time. If you're doing this, you really need to know what you're doing. I used a book called C++/CLI in Action, which I'd recommend.
Edit
This article on STL/CLR looks interesting: http://blogs.msdn.com/b/nikolad/archive/2006/06/16/stlclr-intro.aspx. To quote
STL/CLR, originally called STL.NET, is an implementation of Standard
Template Library (STL) that can operate with objects of managed types.
VC++ already has implementation of STL, however it is currently
working only with native types.
(I can't really help on your Q2)
I want to have named fields rather than indexed fields, but for some usage I have to iterate on the fields. Dumb simplified example:
struct named_states {float speed; float position;};
#define NSTATES (sizeof(struct named_states)/sizeof(float))
union named_or_indexed_states {
struct named_states named;
float indexed[NSTATES];
}
...
union named_or_indexed_states states,derivatives;
states.named.speed = 0;
states.named.position = 0;
...
derivatives.named.speed = acceleration;
derivatives.named.position= states.named.speed;
...
/* This code is in a generic library (consider nstates=NSTATES) */
for(i=0;i<nstates;i++)
states.indexed[i] += time_step*derivatives.indexed[i];
This avoid a copy from named struct to indexed array and vice-versa, and replace it with a generic solution and is thus easier to maintain (I have very few places to change when I augment the state vector).It also work well with various compiler I tested (several versions of gcc/g++ and MSVC).
But theorically, as I understand it, it does not strictly adhere to proper union usage since I wrote named field then read indexed field, and I'm not sure at all we can say that they share same struct fields...
Can you confirm that's it's theorically bad (non portable)?
Should I better use a cast, a memcpy() or something else?
Apart theory, from pragmatic POV is there any REAL portability issue (some incompatible compiler, exotic struct alignment, planned evolutions...)?
EDIT: your answers deserve a bit more clarification about my intentions that were:
to let programmer focus on domain specific equations and release them from maintenance of conversion functions (I don't know how to write a generic one, apart cast or memcpy tricks which do not seem more robust)
to add a bit more coding security by using struct (fully controlled by compiler) vs arrays (decalaration and access subject to more programmer mistakes)
to avoid polluting namespace too much with enum or #define
I need to know
how portable/dangerous is my steering off the standard (maybe some compiler with aggressive inlining will use full register solution and avoid any memory exchange ruining the trick),
and if I missed a standard solution that address above concerns in part or whole.
There's no requirement that the two fields in named_states line up the same way as the array elements. There's a good chance that they do, but you've got a compiler dependency there.
Here's a simple implementation in C++ of what you're trying to do:
struct named_or_indexed_states {
named_or_indexed_states() : speed(indexed[0], position(indexed[1]) { }
float &speed;
float &position;
float indexed[2];
};
If the size increase because of the reference elements is too much, use accessors:
struct named_or_indexed_states {
float indexed[2];
float& speed() { return indexed[0]; }
float& position() { return indexed[1]; }
};
The compiler will have no problem inlining the accessors, so reading or writing speed() and position() will be just as fast as if they were member data. You still have to write those annoying parentheses, though.
Only accessing last written member of union is well-defined; the code you presented uses, as far as only standard C (or C++) is concerned, undefined behavior - it may work, but it's wrong way to do it. It doesn't really matter that struct uses the same type as the type of array - there may be padding involved, as well as other invisible tricks used by compiler.
Some compilers, like GCC, do define it as allowed way to achieve type-punning. Now the question arises - are we talking about standard C (or C++), or GNU or any other extensions?
As for what you should use - proper conversion operators and/or constructors.
This may be a little old-fashioned, but what I would do in this situation is:
enum
{
F_POSITION,
F_SPEED,
F_COUNT
};
float states[F_COUNT];
Then you can reference them as:
states[F_POSITION] and states[F_SPEED].
That's one way that I might write this. I'm sure that there are many other possibilities.
I have a problem with the SLMATH library. Not sure if anyone uses it or has used it before? Anyway, the issue is that when I compile with SSE optimisation enabled (in VS 2010), I obviously have to provide a container that has the correct byte alignment for SSE type objects. This is OK because there's a little class in SLMATH that's an aligned vector; it aligns the vector allocation on an 8 byte boundary (i.e. I do not use std::vector<>).
Now the problem is that it appears any structure or class that contains something like slm::mat4 must also be aligned on such a boundary too, before it's put into a collection. So, for example, I used an aligned vector to create an array of slm::mat4, but if I create a class called Mesh, and Mesh contains an slm::mat4 and I want to put Mesh into a std::vector, well, I get strange memory errors whilst debugging.
So given the documentation is very sparse indeed, can anyone who's used this library tell me what, precisely, I have to do to use it with SSE optimisation? I mean I don't like the idea of having to use aligned vectors absolutely everywhere in place of std::vector just in case an slm:: component ends up being encapsulated into a class or structure somehow.
Alternatively, a fast vector/matrix/graphics math library as good as SLMATH would be great if there's on around.
Thanks for any advice you can offer.
Edit 1: Simple repro-case not using SLMATH illustrates the problem:
#include <vector>
class Item
{
public:
__declspec(align(8))
struct {
float a, b, c, d;
} Aligned;
};
int main()
{
// Error - won't compile.
std::vector<Item> myItems;
}
Robin
It might work if you when you declare your variable to use __declspec(align) on your variable declarations, or to wrap them within a struct that declares itself to be aligned properly. I have not used the library in question, but it seems that this might be the issue you are facing.
The reference for the align option can be found here.
I am running a simulation in which I have objects of a class which use different models. These models are randomly selected for some objects of the class and specifically decided for some objects too. These objects communicate with each other for which I am using structures (aka struct) in C++ which has some
standard variables and
some additional variables which depends on models which the objects communicating with each other have.
So, how can I do this?
Thanks in advance.
You can hack around with:
the preprocessor;
template meta-programming;
inheritance/polymorphism.
Each gives a different way of producing a different user-defined type, based on different kinds of conditions.
Without knowing what you're trying to accomplish, this is the best I can do.
All instances of a structure or class have the same structure. Luckily, there are some tricks that can be used to 'simulate' what you try to do.
The first trick (which can also be used in C), is to use a union, e.g.:
struct MyStruct
{
int field1;
char field2;
int type;
union
{
int field3a;
char field3b;
double field3c;
} field3;
};
In a union, all members take up the same space in memory. As a programmer you have to be careful. You can only get out of the union what you put in. If you initialize one member of a union, but you read another member, you will probable get garbage (unless you want to do some low-level hacks, but don't do this unless you are very experienced).
Unions often come together with another field (outside the union) that indicates which member is actually used in the union. You could consider this your 'condition'.
A second trick is use the 'state' pattern (see http://en.wikipedia.org/wiki/State_pattern). From the outside world, the context class looks always the same, but internally, the different states can contain different kinds of information.
A somewhat simplified approach for state is to use simple inheritance, and to use dynamic casts. Depending on your 'condition', use a different subclass, and perform a dynamic cast to get the specific information.
E.g., suppose that we have a Country class. Some countries have a president, others have a king, others have an emperor. You could something like this:
class Country
{
...
};
class Republic : public Country
{
public:
const string &getPresident() const;
const string &getVicePresident() const;
};
class Monarchy : public Country
{
public:
const string &getKing() const;
const string &getQueen() const;
};
In your application you could work with pointers to Country, and do a dynamic cast to Republic or Monarchy where the president or king is needed.
This example can be easily transformed into one using the 'state' pattern, but I leave this as an exercise for you.
Personally, I would go for the state pattern. I'm not a big fan of dynamic casts and they always seem to be kind-of-hack for me.
If it's at compile-time, a simple #ifdef or template specialization will serve this purpose just fine. If it's at run-time and you need value semantics, you can use a boost::optional<my_struct_of_optional_members>, and if you're fine with reference semantics, inheritance will solve the problem at hand.
A union and that kind of dirty trick is not necessary.
There are several common approaches for "dynamic" attributes/properties in languages, and a few that tend to work well in C++.
For example, you can make a C++ class called "MyProperties" that has a sparse set of values, and your MyStructureClass would have its well-known members, plus a single MyProperties instance which may have zero-or-more values.
Similarly, languages like Python and Perl make extensive use of Associative Arrays/Dictionaries/Hashes to achieve this: The (string) key uniquely identifies the value. In C++, you can index your MyProperties class with a string or any type you want (after overloading the operator[]()), and the value can be a string, a MyVariant, or any other pointer-or-type that you want to inspect. The values are dynamically added to the parent container as they are assigned (e.g., the class "remembers" the last value it is given, uniquely identified by key).
Finally, in the "olden days", what you describe was commonly done for distributed application processing: You defined a C-struct with "well-known" (typed) fields/members, and the last field was a char* member. Then, that char* member would identify the start of a serialized stream of bytes that were also part of that struct (you merely serialized that array of chars when you marshalled the struct across systems). In the context of C++, you could similarly extract your values dynamically from that char* stream buffer on-access-demand (which logically should be "owned" by the class). This worked for marshalling across systems because the size of the struct was the size of everything (including the last char* member), but the "allocation" for that struct was much larger (e.g., the size of the struct itself, which was logically a "header", plus a certain number of bytes after that header, which represented the "payload" and which was indexed by the last member, the char* member.) Thus, it was a contiguous-block-of-memory struct, with dynamic size. (This would also work in C++ as long as you passed-by-reference, and never by value.)
embed an union into your structure, and use a flag to tell which part of the union is valid.
enum struct_type
{
cool,
fine,
bad
};
struct demo
{
struct_type type;
union
{
struct
{
double cool_factor;
} cool_part;
struct
{
int fineness;
} fine_part;
struct
{
char *bad_stuff;
} bad_part;
};
struct
{
int life_is_cool;
} common_part;
};
The pure and simple C++ answer is: use classes.
I can't determine from your question what you are trying to achieve: runtime variation or compile time variation, but either way, I doubt you'll get a workable implementation any other way. (Template metaprogramming aside... which isn't for the faint of heart.)