I need to cast const void * to LLVMValRef ,like this
const void * context;
args[0] = LLVMCastPtrToBoolType((void *) context);
I get the following warning.
warning: cast from type ‘const void*’ to type ‘void*’ casts away qualifiers
Related
i need to do something like this ..., in a project of mine.
class Alpha{
public:
Alpha(void* p(int, int) = nullptr);
void* calculatePointer;
void test();
};
Alpha::Alpha(void* p(int, int)) : calculatePointer(p){};
Alpha::test(){
calculatePointer(5, 10);
}
void calculate(int a, int b){
std::cout << "cum: " << a +b << "\n";
}
int main(){
Alpha A = Alpha(&calculate);
A.test();
}
and it results in in these errors:
error: invalid conversion from ‘void* (*)(int, int)’ to ‘void*’ [-fpermissive]
15 | : calculatePointer(p),
| ^
| |
| void* (*)(int, int)
error: cannot initialize a member subobject of type 'void *' with an lvalue of type 'void *(*)(int, int)'
error: expression cannot be used as a function
In constructor 'Alpha::Alpha(void* (*)(int, int))':
error: invalid conversion from 'void (*)(int, int)' to 'void* (*)(int, int)' [-fpermissive]
note: initializing argument 1 of 'Alpha::Alpha(void* (*)(int, int))'
this is just a dummy, but that's what i gotta do.
how is it done correctly?
If you're confused about the exact syntax of a function pointer it's probably best to define a type alias.
If you use using, the "rhs" is <return type> (*)(<parameter types>)
class Alpha{
public:
using FunctionPtr = void (*)(int, int);
Alpha(FunctionPtr p = nullptr) : calculatePointer(p) {}
FunctionPtr calculatePointer;
void test()
{
if (calculatePointer != nullptr)
{
calculatePointer(5, 10);
}
}
};
void calculate(int a, int b){
std::cout << "sum: " << (a + b) << "\n";
}
Btw: the correct syntax without a type alias would be
Alpha(void (*p)(int, int) = nullptr);
the brackets are necessary, since the compiler treats void *p(int, int) as (void*) p(int, int).
I'm learning as I'm going but while writing these getters for a stat page for a character, I'm getting an error that it is nonstandard, it cant convert the const, and it tells me to add a & "to create a pointer to a member"
I have tried making them pointers with *, I have tried not making them const, making them public, adding any headers that my be missing.
These are the only lines of many that are giving the errors. It produces about 30 errors.
inline const double& getX() const { return this->getX; }
inline const double& getY() const { return this->getY; }
inline const std::string& getName() const { return this->name; }
inline const int& getLevel() const { return this->level; }
inline const int& GetExpNext() const { return this->expNext; }
inline const int& getHP() const { return this->hp; }
inline const int& getStamina() const { return this->stamina; }
inline const int& getDamageMin() const { return this->getDamageMin; }
inline const int& getDamageMax() const { return this->getDamageMax; }
inline const int& getDefense() const { return this->getDefense; }
These are some of the repeating errors.
Error C3867 'Player::getX': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const double &(__thiscall Player::* )(void) const' to 'const double &'
Error C3867 'Player::getY': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const double &(__thiscall Player::* )(void) const' to 'const double &'
Error C3867 'Player::getDamageMin': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const int &(__thiscall Player::* )(void) const' to 'const int &'
Error C3867 'Player::getDamageMax': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const int &(__thiscall Player::* )(void) const' to 'const int &'
Error C3867 'Player::getDefense': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const int &(__thiscall Player::* )(void) const' to 'const int &'
Error C3867 'Player::getX': non-standard syntax; use '&' to create a pointer to member
Error C2440 'return': cannot convert from 'const double &(__thiscall Player::* )(void) const' to 'const double &'
Error C3867 'Player::getY': non-standard syntax; use '&' to create a pointer to member
It's hard to be sure because you've written only posted the lines with the errors instead of posting all the relevant code. but it seems you have written code like this
class Player
{
public:
inline const double& getX() const { return this->getX; }
private:
double x;
};
when you should have written code like this
class Player
{
public:
inline const double& getX() const { return this->x; }
private:
double x;
};
Note x not getX.
And then as has already been pointed out in the comments, inline, this and use of references are all redundant or bad in this case. So you can write the even simpler
class Player
{
public:
double getX() const { return x; }
private:
double x;
};
Just explaining the errors in more detail, as the true answer already is given; you are getting two of these for the same issue:
inline const double& getX() const { return this->getX; }
// ^ ^ (!)
Have you noticed that the two identifiers are the same? At the time you are trying to return getX, the function is already declared and known. And you now are trying to return exactly this function.
Error C3867 'Player::getX': non-standard syntax; use '&' to create a pointer to member
With member functions, you can do two things: Either call them or get their address to form a member function pointer. Unlike free-standing functions and static member functions, non-static member functions are not converted automatically to pointers; for these, you need to explicitly specify the address-of operator &:
void f() { }
class C { public: void f() { } };
void (*pf0)() = &f; // explicitly taking address
void (*pf1)() = f; // works for free standing functions
void (C::*pf0)() = &C::f // ONLY can explicitly take address
//void (C::*pf1)() = C::f // gives you the error you saw already
Well, syntax for function pointers, especially member FP, is really uggly. Usually you are better off defining aliases (typedef or using) or, in above case, you could have used auto.
Error C2440 'return': cannot convert from 'const double &(__thiscall Player::* )(void) const' to 'const double &'
Assuming you already fixed the first error (by adding the required &), then you have a type mismatch between what you declared as return type and what you actually are returning; the former a reference to double, the latter a member function pointer. So you can either adjust the return value (impossible in this case: you'd have to return a pointer to a function returning a pointer to a function returning a pointer to ...) or select the correct member as shown already.
If you wonder about __thiscall: It just is the calling convention, which we usually don't have to specify explicitly (unless we need a non-default one – which usually is the case if e. g. coding against WinAPI).
Why can't I take a reference to s2 in foo? I'm compiling with gcc 5.1.0:
#include <cstring>
void foo(const char*& p)
{
while (*p && *p <= '5')
++p;
}
int main()
{
const char *s1 = "1234567890";
char *s2 = new char[strlen(s1) + 1];
strcpy(s2, s1);
foo(s1); // OK
foo(s2); // error
return 0;
}
I compiled with:
$ g++ test_reference.cpp
The compiler gave me:
test_reference.cpp: In function ‘int main()’:
test_reference.cpp:16:11: error: invalid initialization of non-const reference of type ‘const char*&’ from an rvalue of type ‘const char*’
foo(s2); // error
^
test_reference.cpp:3:6: note: initializing argument 1 of ‘void foo(const char*&)’
void foo(const char*& p)
^
For simplicity, you are trying to do:
char* s = ...;
const char*& r = s;
The const here may be misleading. You would think this is equivalent to:
int i = 4;
const int& ri = i;
Which works. But these are not equivalent. ri here is a reference to a const type, but r is a reference to a pointer to const char, that is not a const type.
The ultimate issue is that char* and char const* are not reference-related (meaning that the types are either the same or in the same hierarchy). However, if your reference was a reference to a const type, it would work fine. That is:
const char* const& cr = s;
Basically, you can take an lvalue reference to a non-const type T only from a reference-related type or from a class that is convertible to a reference related type. But you can take an lvalue reference to a const type from a much wider source of expressions:
double d = 4.0;
int& ri = d; // error: int, double aren't reference-related
const int& rci = d; // OK
You can cast it to const reference.
foo((const char *&) s2);
This question already has answers here:
Why am I getting an error converting a ‘float**’ to ‘const float**’?
(4 answers)
Closed 8 years ago.
In C++, why is it not possible to pass a char** as an argument to a function that accepts const char** , when a conversion from char* to const char* is possible, as shown below
void f1(const char** a)
{
}
void f2(const char* b)
{
}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // doesn't work
f2(c); //works
return 0;
}
The compiler output is
test.cpp: In function 'int main(int, const char**)':
test.cpp:15:10: error: invalid conversion from 'char**' to 'const char**' [-fpermissive]
test.cpp:1:6: error: initializing argument 1 of 'void f1(const char**)' [-fpermissive]
You need to protect contents on both levels of dereference of the pointer. With const char** you could actually modify contents on the 1st dereference.
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(const char** a)
{
a[0] = tmp; //this is legal
a[0][1] = 'x'; //this is not
}
And this is most probably not intended. It should look like this:
char *tmp = "foo"; //Deprecated but it's ok for the example
void f1(char const* const* a)
{
a[0] = tmp; // this is not legal any more
a[0][1] = 'x'; // this still upsets compiler
}
The compiler does not allow implicit conversion to such "partially" protected pointer types. Allowing such conversion could have nasty consequences as discussed in c++faq pointed out in comment by #zmb. This answer also cites how could you violate constness of an object if this was allowed, using char examples.
One can however implicitly convert to a "fully" protected pointer as shown in the 2nd code example so below code compiles.
void f1(char const* const* a){}
void f2(const char* b){}
int main(int argc, char const *argv[])
{
char* c;
f1(&c); // works now too!
f2(c); // works
return 0;
}
Actually there is a bunch of questions and answers on this matter lying around. E.g:
invalid conversion from ‘char**’ to ‘const char**’
Why am I getting an error converting a ‘float**’ to ‘const float**’?
EDIT: I got the 1st example wrong by a bit. Thank for pointing it out!
#include <iostream>
void f(const int * & p)
{
int i =0;
i = p[0];
std::cout << i << std::endl;
}
int main()
{
int * p =new int[1];
p[0] =102;
f(p);
return 1;
}
The gcc compiler gives error for this code:
prog.cpp: In function ‘int main()’:
prog.cpp:16: error: invalid initialization of reference of type ‘const int*&’ from expression of type ‘int*’
prog.cpp:5: error: in passing argument 1 of ‘void f(const int*&)’
But if I change the "f" function into
void f(const int * const & p)
Everything is ok. Can somebody explain why const behaves this way? thanks.
Going from int* to const int* requires creating a temporary const int* pointer and binding the reference const int*& to that temporary.
The Standard forbids doing that creating of a temporary for non-const references. You therefor need to make the reference const as you did your fix.
This is because non-const references mean "I want to change the argument that the caller passes using that reference parameter". But if the caller needs to convert their argument and ends up passing a temporary, the point of the reference is for naught, and so the Standard deems it an error to try and pass the temporary.
If the first conversion (int * to const int * &) were allowed, then you could write an evil function like this:
const int really_const[] = {1,2,3};
void evil(const int * & p)
{
p = really_const;
}
int main()
{
int not_const[3];
int * p = not_const;
evil(p);
p[0] = 0; // Whoops: modifying a const object
}
The second conversion is fine, since it prevents the function from modifying the pointer in this way.