I need to call an API function which needs a struct-pointer as a parameter.
lets say its this struct
struct SomeObject{
double a;
double b;
}
and this function to call: func(SomeObject*)
The problem here is that I only have access to data as a custom struct but the same structure like SomeObject given as an vector.
struct CustomObject{
double a;
double b;
}
And the compiler is throwing errors because they are different parameters. cannot convert 'std::vector<CustomObject>' to 'SomeObect*' in argument passing. I tried already to pass the CustomObject as a pointer but its of course still a different Object.
Is there any chance to get this working what I am trying to do? And what could be a possible approach?
You can't pass a std::vector to a function that expects a pointer. If the function expects a pointer to an array, then you can get that pointer using std::vector::data
Now, that leaves us with the problem that the vector contains objects of a wrong type. The pointer returned by std::vector::data will be of type CustomObject* while you need SomeObject*. They're unrelated, but identical types and luckily, standard layout types. As long as those two requirements hold, that gives us the guarantee that the types have the same representation. Therefore, we can simply cast the pointer with reinterpret_cast:
func(reinterpret_cast<SomeObject *>(vec.data()));
The compiler is now showing 'cast away qualifiers'. It seems to have a problem with because CustomObject is currently a const.
I take that to mean that the vector is const, or it's a vector of const objects. In that case you shouldn't pass it's data to a function that takes a pointer to non-const. But if you know that the function will not modify the objects, despite taking a pointer to non-const, and you want to get rid of the compiler warning, then you must cast the constness away explicitly, using const_cast.
reinterpret_cast might have 'solved' the problem, but has made your code incredibly brittle. I'd really not recommend that approach.
Instead I'd manually construct a SomeObject from the CustomObject:
SomeObject x;
x.a = myCustomObj.a;
x.b = myCustomObj.b;
func(&x);
This also avoids the const issue. Don't even think about optimizations or efficiency at this stage. YAGNI.
func((SomeObject *)&obj[0]);
Related
Here's some code from the PhysX examples:
std::vector<PxRigidActor*> actors(nbActors);
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC,
reinterpret_cast<PxActor**>(&actors[0]), nbActors);
And then in the code of the getActors function they use it like this:
PxU32 NpScene::getActors(PxActorTypeFlags types, PxActor** buffer, PxU32 bufferSize, PxU32 startIndex=0) const
{
...
if ((types & PxActorTypeFlag::eRIGID_STATIC ) && mRigidActors[i]->is<PxRigidStatic>())
{
if (virtualIndex >= startIndex)
buffer[writeCount++] = mRigidActors[i];
virtualIndex++;
}
else if ((types & PxActorTypeFlag::eRIGID_DYNAMIC) && mRigidActors[i]->is<PxRigidDynamic>())
{
if (virtualIndex >= startIndex)
buffer[writeCount++] = mRigidActors[i];
virtualIndex++;
}
...
}
mRigidActors is defined as Ps::Array<PxRigidActor*>
The inheritance diagram looks like this:
So, my questions are:
I heard that the pointer to the parent class can point to the instance of the child class. Then, why do we need any casting at all? I tried, but without casting it doesn't work.
Is it safe to use reinterpret_cast as it is used here?
(I suppose yes, because it's just pointers conversion)
Is there a better solution?
I heard that the pointer to the parent class can point to the instance of the child class. Then, why do we need any casting at all? I tried, but without casting it doesn't work.
There is an implicit conversion from PxRigidActor* to PxActor* (a derived-to-base pointer conversion), but there is no such relationship between PxRigidActor** and PxActor**
Is it safe to use reinterpret_cast as it is used here? (I suppose yes, because it's just pointers conversion)
The cast is not itself unsafe, but it is undefined behaviour to dereference the pointer created by the cast.
Is there a better solution?
Define actors with an appropriate type in the first place, i.e.
std::vector<PxActor*> actors(nbActors);
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, actors.data(), nbActors);
You can then static_cast<PxRigidActor*> the elements of actors as needed.
reinterpret_cast<PxActor**>(&actors[0])
is casting the address of the first element of the vector, not casting the element itself.
Furthermore, the called function is treating the pointer as an array. That is, it is casting the .data() of the vector to a different type of element.
You would expect static_cast to be used when navigating between base/derived class references or pointers. But that highlights an issue: The cast might modify the address, if the base class instance is not at the beginning of the derived class! The reinterpet_cast avoids this and just changes the type without changing the value... but if such a value change was necessary, this code would not work right anyway. By casting the "out" parameter's address instead of the value in that address, the code has no idea that anything stored in that slot needs to be adjusted back to the real type.
Since he's casting a pointer to the pointer, the static_cast would not work directly in the same place. It's a double pointer, and that doesn't follow the rule of D* to B*. It would have to write the static_cast
as a reference cast, and then take the address of that. Off the top of my head, something like &static_cast<PxActor*&>(actors.data()) (that might have the same issue; I'd have to bang on it to get something working, probably not as a single expression; and I have no intention of trying to do that.)
My guess is that he converted a legacy C cast to reinterpet_cast and didn't think too much about it, or saw that only this one worked (in the same place as the legacy cast).
but why?
The code populates a contiguous collection of the base class pointer. It takes an out parameter instead of returning a vector, and the caller wants that vector defined as a derived type instead of the base type. Normally it should be just fine to keep it as the base class since the behavior is presumably polymorphic.
This is copying from different source collections, with identical code in each branch. It probably ought to be generic, or use the visitor pattern. That would avoid most of the type casting issues.
X is defined as the following:
struct X
{
Y y;
// more fields...
int a;
};
I have a variable of type X. However, I would like to cast it to the type of its first member, in order to pass that into a function. I know that the C Standard permits it (and I suppose the C++ one does so as well).
In C I would do it like so:
X x;
Y* y = (Y*) x;
doStuff(y);
What type of cast is the right one in C++ for this? static_cast or reinterpret_cast?
None.
You can't mess around with objects using pointers like that. C++ is not C, and these are not "just bytes" (contrary to popular belief).
And you don't need to!
Pass &x.y instead; it's already the Y* you want.
I'd always recommend using static_cast instead of reinterpret_cast in any situation where the static_cast isn't rejected by the compiler. If possible try to avoid doing any casting at all - in this case you probably want: Y* y = &x.y.
To answer the comment:
In this case, I have a PROCESS_MEMORY_COUNTERS_EX
variable. However the WinAPI function GetProcessMemoryInfo takes a
PROCESS_MEMORY_COUNTERS*. The former type starts with the exact same
fields as the latter, and adds a few at the end. The intended usage is
to pass into the function a pointer to the latter type, even if we
hold a pointer to the former (larger) type.
The documentation for GetProcessMemoryInfo() states that the second parameter is:
A pointer to the PROCESS_MEMORY_COUNTERS or PROCESS_MEMORY_COUNTERS_EX
structure that receives information about the memory usage of the
process.
The Win32 API is a C API, and not a C++ one, so you can just use a C style cast here, or preferably a reinterpret_cast to make your intention clearer. I'd expect static_cast to be rejected by the compiler in this case. Note that the third cb parameter is there to tell the function which type of structure you actually provided - it should be set to either sizeof(PROCESS_MEMORY_COUNTERS) or sizeof(PROCESS_MEMORY_COUNTERS_EX).
#FredLarson In this case, I have a PROCESS_MEMORY_COUNTERS_EX variable. However the WinAPI function GetProcessMemoryInfo takes a PROCESS_MEMORY_COUNTERS*. The former type starts with the exact same fields as the latter, and adds a few at the end. The intended usage is to pass into the function a pointer to the latter type, even if we hold a pointer to the former (larger) type.
The cleanest way to accomplish that would be probably (ab)using inheritance. This way, you can have your _EX type share members with the base type while actually being an instance of it.
struct X {
int a;
int b;
};
struct X_EX : public X {
int other_member;
};
void doStuff(X*);
void foo(X_EX* ptr) {
doStuff(ptr);
}
However, do note that "Inherit-to-extend" is seen as a code smell, and something to avoid if possible nowadays. I'd make sure to put a comment explaining why it's necessary here.
I keep hearing this statement, while I can't really find the reason why const_cast is evil.
In the following example:
template <typename T>
void OscillatorToFieldTransformer<T>::setOscillator(const SysOscillatorBase<T> &src)
{
oscillatorSrc = const_cast<SysOscillatorBase<T>*>(&src);
}
I'm using a reference, and by using const, I'm protecting my reference from being changed. On the other hand, if I don't use const_cast, the code won't compile. Why would const_cast be bad here?
The same applies to the following example:
template <typename T>
void SysSystemBase<T>::addOscillator(const SysOscillatorBase<T> &src)
{
bool alreadyThere = 0;
for(unsigned long i = 0; i < oscillators.size(); i++)
{
if(&src == oscillators[i])
{
alreadyThere = 1;
break;
}
}
if(!alreadyThere)
{
oscillators.push_back(const_cast<SysOscillatorBase<T>*>(&src));
}
}
Please provide me some examples, in which I can see how it's a bad idea/unprofessional to use a const_cast.
Thank you for any efforts :)
Because you're thwarting the purpose of const, which is to keep you from modifying the argument. So if you cast away the constness of something, it's pointless and bloating your code, and it lets you break promises that you made to the user of the function that you won't modify the argument.
In addition, using const_cast can cause undefined behaviour. Consider this code:
SysOscillatorBase<int> src;
const SysOscillatorBase<int> src2;
...
aFieldTransformer.setOscillator(src);
aFieldTransformer.setOscillator(src2);
In the first call, all is well. You can cast away the constness of an object that is not really const and modify it fine. However, in the second call, in setOscillator you are casting away the constness of a truly const object. If you ever happen to modify that object in there anywhere, you are causing undefined behaviour by modifying an object that really is const. Since you can't tell whether an object marked const is really const where it was declared, you should just never use const_cast unless you are sure you'll never ever mutate the object ever. And if you won't, what's the point?
In your example code, you're storing a non-const pointer to an object that might be const, which indicates you intend to mutate the object (else why not just store a pointer to const?). That might cause undefined behaviour.
Also, doing it that way lets people pass a temporary to your function:
blah.setOscillator(SysOscillatorBase<int>()); // compiles
And then you're storing a pointer to a temporary which will be invalid when the function returns1. You don't have this problem if you take a non-const reference.
On the other hand, if I don't use const_cast, the code won't compile.
Then change your code, don't add a cast to make it work. The compiler is not compiling it for a reason. Now that you know the reasons, you can make your vector hold pointers to const instead of casting a square hole into a round one to fit your peg.
So, all around, it would be better to just have your method accept a non-const reference instead, and using const_cast is almost never a good idea.
1 Actually when the expression in which the function was called ends.
by using const, I'm protecting my reference from being changed
References can't be changed, once initialized they always refer to the same object. A reference being const means the object it refers to cannot be changed. But const_cast undoes that assertion and allows the object to be changed after all.
On the other hand, if I don't use const_cast, the code won't compile.
This isn't a justification for anything. C++ refuses to compile code that may allow a const object to be changed because that is the meaning of const. Such a program would be incorrect. const_cast is a means of compiling incorrect programs — that is the problem.
For example, in your program, it looks like you have an object
std::vector< SysOscillatorBase<T> * > oscillators
Consider this:
Oscillator o; // Create this object and obtain ownership
addOscillator( o ); // cannot modify o because argument is const
// ... other code ...
oscillators.back()->setFrequency( 3000 ); // woops, changed someone else's osc.
Passing an object by const reference means not only that the called function can't change it, but that the function can't pass it to someone else who can change it. const_cast violates that.
The strength of C++ is that it provides tools to guarantee things about ownership and value semantics. When you disable those tools to make the program compile, it enables bugs. No good programmer finds that acceptable.
As a solution to this particular problem, it looks likely that the vector (or whatever container you're using) should store the objects by value, not pointer. Then addOscillator can accept a const reference and yet the stored objects are modifiable. Furthermore, the container then owns the objects and ensures they are safely deleted, with no work on your part.
The use of const_cast for any reason other than adapting to (old) libraries where the interfaces have non-const pointers/references but the implementations don't modify the arguments is wrong and dangerous.
The reason that it is wrong is because when your interface takes a reference or pointer to a constant object you are promising not to change the object. Other code might depend on you not modifying the object. Consider for example, a type that holds an expensive to copy member, and that together with that it holds some other invariants.
Consider a vector<double> and a precomputed average value, the *average is updated whenever a new element is added through the class interface as it is cheap to update then, and if it is requested often there is no need to recompute it from the data every time. Because the vector is expensive to copy, but read access might be needed the type could offer a cheap accessor that returns a std::vector<double> const & for user code to check values already in the container. Now, if user code casts away the const-ness of the reference and updates the vector, the invariant that the class holds the average is broken and the behavior of your program becomes incorrect.
It is also dangerous because you have no guarantee that the object that you are passed is actually modifiable or not. Consider a simple function that takes a C null terminated string and converts that to uppercase, simple enough:
void upper_case( char * p ) {
while (*p) {
*p = ::to_upper(*p);
++p;
}
}
Now lets assume that you decide to change the interface to take a const char*, and the implementation to remove the const. User code that worked with the older version will also work with the new version, but some code that would be flagged as an error in the old version will not be detected at compile time now. Consider that someone decided to do something as stupid as upper_case( typeid(int).name() ). Now the problem is that the result of typeid is not just a constant reference to a modifiable object, but rather a reference to a constant object. The compiler is free to store the type_info object in a read-only segment and the loader to load it in a read-only page of memory. Attempting to change it will crash your program.
Note that in both cases, you cannot know from the context of the const_cast whether extra invariants are maintained (case 1) or even if the object is actually constant (case 2).
On the opposite end, the reason for const_cast to exist was adapting to old C code that did not support the const keyword. For some time functions like strlen would take a char*, even though it is known and documented that the function will not modify the object. In that case it is safe to use const_cast to adapt the type, not to change the const-ness. Note that C has support for const for a very long time already, and const_cast has lesser proper uses.
The const_cast would be bad because it allows you to break the contract specified by the method, i.e. "I shall not modify src". The caller expects the method to stick to that.
It's at least problematic. You have to distinguish two constnesses:
constness of the instantiated variable
This may result in physical constness, the data being placed in a read-only segment
constness of the reference parameter / pointer
This is a logical constness, only enforced by the compiler
You are allowed to cast away the const only if it's not physically const, and you can't determine that from the parameter.
In addition, it's a "smell" that some parts of your code are const-correct, and others aren't. This is sometimes unavoidable.
In your first example, you assign a const reference to what I assume is a non-const pointer. This would allow you to modify the original object, which requires at least a const cast. To illustrate:
SysOscillatorBase<int> a;
const SysOscillatorBase<int> b;
obj.setOscillator(a); // ok, a --> const a --> casting away the const
obj.setOscilaltor(b); // NOT OK: casting away the const-ness of a const instance
Same applies to your second example.
, while I can't really find the reason why const_cast is evil.
It is not, when used responsibily and when you know what you're doing. (Or do you seriously copy-paste code for all those methods that differ only by their const modifier?)
However, the problem with const_cast is that it can trigger undefined behavior if you use it on variable that originally was const. I.e. if you declare const variable, then const_cast it and attempt to modify it. And undefined behavior is not a good thing.
Your example contains precisely this situation: possibly const variable converted into non-const. To avoid the problem store either const SysOscillatorBase<T>*(const pointer) or SysOscillatorBase<T> (copy) in your object list, or pass reference instead of const reference.
You are violating a coding contract. Marking a value as const is saying you can use this value but never change it. const_cast breaks this promise and can create unexpected behaviour .
In the examples you give, it seems your code is not quite right. oscillatorSrc should probably be a const pointer, although if you really do need to change the value then you should not pass it in as a const at all.
Basicly const promises you and the compiler that you will not change the value. The only time you should use when you use a C library function (where const didn't exist), that is known not to change the value.
bool compareThatShouldntChangeValue(const int* a, const int* b){
int * c = const_cast<int*>(a);
*c = 7;
return a == b;
}
int main(){
if(compareThatShouldntChangeValue(1, 7)){
doSomething();
}
}
You probably need to define you container as containing const objects
template <typename T> struct Foo {
typedef std::vector<SysOscillator<T> const *> ossilator_vector;
}
Foo::ossilator_vector<int> oscillators;
// This will compile
SysOscillator<int> const * x = new SysOscillator<int>();
oscillators.push_back(x);
// This will not
SysOscillator<int> * x = new SysOscillator<int>();
oscillators.push_back(x);
That being said if you have no control over the typedef for the container maybe it
is ok to const_cast at the interface between your code and the library.
i have a specific problem with pointers and references, with std::vector and std::string. Some question are in the following code snipped, some below.
I have basically this code
//first of all: is this function declaration good?
//or shoudl I already pass the std::vector in another way?
//I'm only reading from it
void func(const std::vector<std::string>& vec)
{
//I need to call otherFunc(void*) with a single element from vec:
//otherFunc(void* arg);
//with arg being a void* to vec[0]
}
My IDE tells me that only &*vec[0] works as parameter for otherFunc, but this doesn't compile...
How is the best way to do these kind of parameter passing?
That is a good declaration, as long as the function is not intended to modify the vector. It's more efficient than passing by value, since it avoids copying the vector - an expensive operation requiring a memory allocation.
However, the other function requires a non-const pointer. How to handle this depends on whether it might modify the data.
If it won't (as you imply when you say "I'm only reading from it") then the options are:
Change it to otherFunc(void const * arg) to give a stronger guarantee that it won't, or
Remove the const qualification with a const_cast<void*> when calling it
Note that &*vec[0] won't compile; you want vec[0].c_str() to get a C-compatible pointer to the first string's data, assuming that's what you need.
If it might modify the vector, then you'll have to do something else, since there's no legal way to modify a std::string through a pointer to its data. Probably the best option is to use std::vector<char> rather than std::string, but that depends on exactly what the function does.
First of all, since you only read from the vector, passing it as a const reference is a good idea and should work well.
To your second question: it is difficult to say what otherFunc will do to your object, since it expects a void pointer. This is C style and should not be used in C++, there are better and type safe ways to do so.
Firstly, &*vec[0] is meaningless; you probably mean &vec[0] (i.e. the address of the first string in your vector).
But even this won't compile because &vec[0] is of type const std::string *. Most importantly, it's const. You could do this:
otherFunc(const_cast<std::string *>(&vec[0]));
BUT!!! Trying to use a const std::string * in the context of a void * sounds like a very bad idea. How could that possibly ever do anything useful?
Normal pointers can be stored using a generic void*. e.g.
void* arr[10];
arr[0] = pChar;
arr[1] = pINt;
arr[2] = pA;
Sometime back, I came across a discussion that, void* may not be capable enough to store a function pointer without data-loss in all platforms (say 64-bit and more). I am not sure about this fact though.
If that's true, then what is the most portable way to store a collection of function pointers ?
[Note: This question doesn't satisfactorily answer this.]
Edit: I will be storing this function pointers with an index. There is a typecasting associated with every index whenever this collection is accessed. As of now, I am interested only to make an array or vector of it.]
You can convert a function pointer to another function pointer of any function type and back without loss.
So as long as when you make the call through the function pointer you typecast it back to the correct type first, you can store all of your function pointers in something like:
typedef void (*fcn_ptr)(void); // 'generic' function pointer
fcn_ptr arr[10];
A pointer to a function can be converted to a pointer to a function of a different type with a reinterpret_cast. If you convert it back to the original type you are guaranteed to get the original value back so you can then use it to call the function. (ISO/IEC 14882:2003 5.2.10 [expr.reinterpret.cast] / 6)
You now only need to select an arbitrary function pointer type for your array. void(*)() is a common choice.
E.g.
int main()
{
int a( int, double );
void b( const char * );
void (*array[])() = { reinterpret_cast<void(*)()>(a)
, reinterpret_cast<void(*)()>(b) };
int test = reinterpret_cast< int(*)( int, double) >( array[0] )( 5, 0.5 );
reinterpret_cast< void(*)( const char* ) >( array[1] )( "Hello, world!" );
}
Naturally, you've lost a lot of type safety and you will have undefined behavior if you call a function through a pointer to a function of a different type.
Use a union of your function pointer types, this works in both C and C++ and assures sufficient storage for the pointers (which are likely the same size, still...)
There are a few things that make up a function pointer's type.
the memory address of the code
the argument signature
the linkage/name mangling
the calling convention
for member functions, some other stuff too
If these features aren't uniform across your function pointers then you can't sensibly store them in the same container.
You can, however bind different aspects into a std::function which is a callable object that only requires the argument signature and return type to be uniform.
It may be a good time to re-think the problem in terms of virtual functions. Does this mishmash of function pointers have a coherent interface that you can express? If not, then you're doomed anyway :-)
RE: Hasturkun, you can store heterogeneous function pointers in unions, yes, they're just POD, but you will also need to store information about what type of pointer it is so that you can choose the correct member to call. Two problems with this:
there is a per-item overhead,
you have to manually check that you're using the right one consistently all the time, this is a burden with nonlocal effects -- it's a spreading poison.
Far better to have one container per type, it will clarify the code and make it safer. Or, use a proxy such as std::function to make them all have the same type.