I noticed that I can speed up compile times (significantly) by hiding complicated objects as void* pointers in my class, and dealing with them in a isolated cpp. Forward declaring these classes is too hard to maintain.
Using a macro sometimes works, but sometimes it doesn't. Does anybody know of a way to shadow a variable with a cast so that I can get l-value? Is there something I can do with a structure that has an implicit cast operator that can give me an l-value. Is there some paradigmatic way to handle these problems that I'm not seeing?
struct K : CGAL::Exact_predicates_inexact_constructions_kernel {};
typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
typedef Triangulation::Vertex_handle Vertex_handle;
#define Triangulation_Ptr (static_cast<Triangulation*>(this->Triangulation_Ptr))
void MyClass::cleanTriangulation()
{
delete Triangulation_Ptr;//works, this->Triangulation_Ptr is a void*
}
void MyClass::addToTriangulation(int idx, MyPoint l)
{
if (Triangulation_Ptr == nullptr)
{
Triangulation_Ptr = new Triangulation;// No a l-value, doesn't compile
}
//something, that adds a point
}
You will get a lot of people suggesting you don't do this, but I share your pain. Quite apart from compile times, the careful design and use of a layer of typedefs, templates and even macros can produce code in which the business logic is far easier to understand, even if the underlying code is not. You leave yourself open to occasional weird compile errors, but in my view the effort is worth it in carefully chosen situations.
Having said that, what you are trying to is not necessarily easy to achieve. If you're going to use macros, you want to flag them in a way that those who use them know what they're playing with.
Does something like this work?
#define Triangulation_Ptr (Triangulation*)(&this->Triangulation_Ptr)
Part of the problem is that these are pointer-to-member, which are really not the same as ordinary pointers.
Related
I'd like to get deeper in C++. There are decisions made in STL that I'd like to understand and it's quite hard from just the code.
My idea is to implement some of the STL on my own to understand the pitfalls and so improve my understanding of C++ and improve my code. And I'd like to have some features in STL containers the STD does not have like destruction notification for a resource handling class. I created an extended version of my SharedPointer to contain a std::function as deletion notifier.
And I found some trouble.
Take this code for example: SmartPointer.hpp
This is some code I came up with and have some questions.
Short:
Known problems
Derived classes won't work
Complains about incomplete type
Unknown problems
Long:
1.1. Derived classes won't work
Just having T as type won't work after the type has been casted. The idea was to pass along OrigT as second parameter so I always know what type ptr points to. I can cast it back and call the correct destructor.
Considering
SharedPointer<Derived> member = base.Cast<Derived>();
will create T = OrigT and types will not match after cast on assertion I assume. I can't imagine anything how I could solve this.
if (!shared->HasReferences())
{
delete shared;
OriginalValuePointer origPtr = dynamic_cast<OriginalValuePointer>(ptr);
delete origPtr;
}
1.2. Complains about incomplete type
In my examples I get complaints about incomplete type. But I can't figure out why. Currently I am considering making operator* and operator-> templates, too that would be a shot in the dark. I have no clue why it complains and I'd like to ask if you could point me to the problem here.
Same code as above in compiler complaint
2.2. I think stackoverflow is not the ideal place to ask for feedback but considering my two problems I'd like to ask anyway.
Does anyone have any sources to readable and ideally explained smart pointers? The ones I've found did not quite match my expectations. They were either too simple or did not contain explanation at the critical points.
I'd appreciate some direct feedback on the code. Afar from coding style of course ;-). Is there anything you directly see where I made a mistake I'll regret? Is there anything that could be done better? (for example, .Cast as member is IMHO a bad choice. For once it is not directly a property of the pointer and I think it might cause flaws I'm not aware of yet.)
I'm really grateful for your help and your opinion.
Stay healthy.
Normal C++ classes use snake_case, rather than CamelCase.
This class isn't' thread safe (you probably knew that, but its worth calling out)
NumReferences returns the count by reference, which isn't useful, and is slightly slower than returning by int.
All methods defined inside the class are automatically inline, so you don't need that anywhere.
operator ValueType() is implicit, which is super dangerous. You can make it explicit, but I'd eliminate it entirely.
operator ValueType() needs to know the details of ValueType in order to be created. So if ValueType isn't fully defined yet, you'll get compiler errors about an incomplete type. Again, deleting the method eliminates this issue.
operator SharedPointer<U>() and operator bool() are also implicit. Prefer explicit.
strongly consider adding assert to all your methods that use shared or ptr without checking if it's null first.
Raw() is normally named get()
Now, on to OrigT and Release: std::shared_ptr does an interesting trick where the SharedData has inheritance:
struct SharedData {
std::atomic_uint count;
virtual ~SharedData() {}
};
template<class OrigT>
struct SharedDataImpl {
OrigT* data;
~SharedData() {delete data;}
};
Since all the shared_ptrs to the same data will point to the same SharedDataImpl, they don't have to know the most derived class. All they have to do is delete the SharedData member, and it'll automatically clean up the data correctly. This does require having a second data pointer: one in the SharedPointer itself and one in the SharedData, but usually this isn't an issue. (Or a virtual T* get() method)
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.
My current project code base has every unit and its friend refined.
Extract :-
...
typedef int m; // meter
typedef int htz;
typedef int s; // second
...
Good or Bad?
I hate it! Its a pain, there is no benefit, and "m" globally defined, omg!
But I want to state the reason why I hate it, in a bit more of technical/articulate manor... hello readers!
Can people list For/Against arguments for this pattern? Many thanks.
Better to make them custom types, as then you can control conversions and overload operators. Right now, I can do meaningless things like multiply a metre by a hertz. Ideally, m / s would yield a velocity- but it won't. It's meaningless to just typedef them like that.
Presumably they are trying to document intent, but without type safety there is no enforcing it. It is just clutter that increases the barrier of entry for reasoning about the code.
Even if they did try and create type safety, trying to abstract data at low levels just adds complexity. It doesn't make solving problems easier. The variable name describes the contents well enough anyway.
I was having a look at the "Function" class documentation in Boost, and stumbled across this:
boost::function<float (int x, int y)> f;
I must admit this syntax is highly confusing for me. How can this be legal C++ ?
Is there any trick under the hood ? Is this syntax documented anywhere?
[Edit] This is an answer to the author's original, unedited question which was actually two questions.
I must admit this syntax is highly
confusing for me. How can this be
legal C++ ? :) Is there any trick
under the hood ? Is this syntax
documented anywhere ?
This is perfectly legal and it's actually not too complicated.
template <class T>
class C
{
public:
T* function_pointer;
};
void fn(int x)
{
cout << x << endl;
}
int main(int argc, char** argv)
{
C<void (int x)> c;
c.function_pointer = &fn;
c.function_pointer(123); // outputs x
}
It's basically the same thing as doing:
typedef void Function(int);
C<Function> c;
This type is not just applicable C++, it's just as applicable in C (the actual type C is parameterized to). The template magic here is taking something like the Function typedef here and being able to detect the types of the return values and arguments. Explaining that would be too lengthy here and boost::function uses a lot of the function traits meta-templates in boost to retrieve that information. If you really want to spend the time to learn this, you should try to understand the boost implementation starting with boost::function_traits in Boost.Type Traits.
However, I want to address your general problem. I think you are trying too hard to simplify a couple of lines of perfectly acceptable code. There's nothing wrong with passing the arguments for your command subclasses through their parameterized subclass constructors. Is is really worth trying to involve typelists and boost::function-like solutions here, thereby increasing compile times and code complexity significantly, just for that?
If you want to reduce it further, just write an execute function that will execute any command subclass and add it to the undo stack and so on:
typedef boost::shared_ptr<Command> CommandPtr;
void execute(const CommandPtr& cmd)
{
cmd->execute();
// add command to undo stack or whatever else you want to do
}
// The client can simply write something like this:
execute(CommandPtr(new CmdAdd(some_value) );
I really think the trade-off of trying to make it any more complicated isn't worth it. The boost authors wanted to write an extremely general-purpose solution for boost::function which would be used by many people across many platforms and compilers. However, they didn't try to generalize a command system capable of executing functions with different signatures across a unified undo system (thereby requiring the state of these commands to be preserved even after one is initially finished calling them and be able to undo and re-execute them without re-specifying the original state data on subsequent executions). For that, your inheritance-based approach is most likely the best and most straightforward one.
I inherited a big application that was originally written in C (but in the mean time a lot of C++ was also added to it). Because of historical reasons, the application contains a lot of void-pointers. Before you start to choke, let me explain why this was done.
The application contains many different data structures, but they are stored in 'generic' containers. Nowadays I would use templated STL containers for it, or I would give all data structures a common base class, so that the container can store pointers to the base class, but in the [good?] old C days, the only solution was to cast the struct-pointer to a void-pointer.
Additionally, there is a lot of code that works on these void-pointers, and uses very strange C constructions to emulate polymorphism in C.
I am now reworking the application, and trying to get rid of the void-pointers. Adding a common base-class to all the data structures isn't that hard (few days of work), but the problem is that the code is full of constructions like shown below.
This is an example of how data is stored:
void storeData (int datatype, void *data); // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);
This is an example of how data is fetched again:
Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);
I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.
Any tips on how to find, replace, or interact in any possible way with these conversions?
I actually want to replace all the
void-pointers with some smart-pointer
(reference-counted), but I can't find
a trick to automate (or at least) help
me to get rid of all the casts to and
from void-pointers.
Such automated refactoring bears many risks.
Otherwise, sometimes I like to play tricks by making out of such void* functions the template functions. That:
void storeData (int datatype, void *data);
becomes:
template <class T>
void storeData (int datatype, T *data);
At first implement template by simply wrapping the original (renamed) function and converting the types. That might allow you to see potential problems - already by simply compiling the code.
You probably don't need to get rid of the casts to use shared pointers.
storeData(TYPE_CUSTOMER, myCustomer1->get());
shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");
Of course, this assumes that you don't expect to share the same pointer across calls to store/fetch. In other words, myCustomer1 and myCustomer2 don't share the same pointer.
Apparently, there is no automated way/trick to convert or find all uses of void-pointers. I'll have to use manual labor to find all void-pointers, in combination with PC-Lint that will give errors whenever there is an incorrect conversion.
Case closed.