I do not understand why line 21 is ok but line 25 is error?
The error message:
invalid conversion from 'const int*' to 'int*' [-fpermissive]
Push is function in class that decleared like this:
template< typename Type >
class Stack {
void Push(const Type& value) {
SNode* type = new SNode();
if (this->head != nullptr) {
this->head->up = temp;
}
temp->value = value;
temp->up = nullptr;
temp->down = head;
temp->head = temp;
num_of_elements++;
}
};
int main() {
Stack<int*>* stk = new Stack<int*>();
int a = 5;
int* x = &a;
stk->Push(x); //this line is fine
const int b = 5;
const int* y = &b;
stk->Push(y); //this line is an error
delete stk;
return 0;
}
It's look like function Push get parameter from type of "const int * &" , and in line 25 , i exactly sends a const pointer "const int *". so what is the problem?
The Push() in line 21
int a = 5;
int * x = &a;
stk->Push(x);
where Push() wait for a const Type & value (with Type equal to int *, if I understand correctly), works because you're sending a int * to a method that is wainting for a compatible type, a const Type & that is int * const &.
Remember that const is applied on the left, on the right when there isn't nothing on the left, so const Type & is Type const & that is int * const &. So is a reference to a constant pointer to a not-constant integer.
When you write (Push() in line 25)
const int b = 5;
const int * y = &b;
stk->Push(y);
you're sending a const int *, that is a int const * (not-constant pointer to a constant integer), to a method that is waiting for a int * const & (a reference to a constant pointer to a not-constant integer).
The two types are incompatibles, so the error.
You can try with
int b = 5;
int * const y = &b;
stk->Push(y);
This should work.
Related
Is there any way I could write the two lines (7 and 8) of code into one line? I think I understand why the error occurs.
int value = 5;
int &GetValue() { return value; }
int main() {
const int *my_value = (const int *)&(GetValue()); // 7
const int *const *my_value_pp = (const int *const *)&(my_value); // 8
// This gives error for saying cannot take the address of an rvalue of type 'int *'
// const int* const * my_second_value_pp = (const int* const*)(&(&(Getvalue()));
}
I need this since there is a function (which I did not write) that takes a const int *const * as an argument.
First, the two lines does not require casting, so just write:
const int* my_value = &GetValue(); // 7
const int* const* my_value_pp = &my_value; // 8
You can however not write that as a one-liner as the function you are going to call needs the address of my_value. You can however skip my_value_pp and call your function using my_value directly:
void func(const int* const*) {} // example function taking a const int* const*
func(&my_value); // &my_value is a const int**
I have a Test class with overloaded constructor. Initializing const char array member by string literals work fine. But, initialization by const char * gives error -
error: incompatible types in assignment of ‘const char*’ to ‘const
char [25]’
class Test
{
const char d_arr[25];
public:
Test() : d_arr("Test Class") {}
Test(const char * arr) : d_arr(arr) {}
};
How to resolve this?
You are assigning a pointer to an array, which is not allowed.
i.e. You cannot do following:
const char *arr = "ABC";
const char d_arr[25] = arr;
What you need to do is copy the chars manually i.e. something like:
Test(const char * arr) {
size_t index = 0;
if (arr) {
while (arr[index] && index < 24) {
d_arr[index] = arr[index];
++index;
}
}
d_arr[index] = 0;
}
That all said, as said in comments, its better to use std::string.
When I try to call a function, passing in a reference to my variable which has the type int, to the function which takes a type of int, I get an error that seems to point out that the int is the type of the class it was declared in, why is this?
Header:
class MyClass {
public:
int MAJOR = 3;
int MINOR = 3;
int REV = 0;
}
Code:
glfwGetVersion(&MyClass::OPENGL_VERSION_MAJOR, &MyClass::OPENGL_VERSION_MINOR, &MyClass::OPENGL_VERSION_REV);
Error:
error: cannot convert 'int MyClass::*' to 'int*' for argument '1' to 'void glfwGetVersion(int*, int*, int*)'
Change to:
class MyClass {
public:
static const int MAJOR = 3;
static const int MINOR = 3;
static const int REV = 0;
};
If these versions are constant.
Otherwise as:
class MyClass {
public:
static int MAJOR;
static int MINOR;
static int REV;
};
Then somewhere in a .cpp file
int MyClass::MAJOR = 3;
int MyClass::MINOR = 3;
int MyClass::REV = 0;
Check live example here
&MyClass::OPENGL_VERSION_MAJOR is a pointer on member.
You may use
MyClass instance;
glfwGetVersion(&instance.OPENGL_VERSION_MAJOR,
&instance.OPENGL_VERSION_MINOR,
&instance.OPENGL_VERSION_REV);
I 'm still confused for my problem after spending an amount of time to digging related posts/online resources.
My sample codes (test.cc) are :
void testsub(const int* &xx );
int main ()
{
int* xx;
xx= new int [10];
testsub(xx);
}
void testsub(const int* & xx){}
The compiling error message(pgcpp) read
"test.cc", line 7: error: a reference of type "const int *&" (not const-qualified)
cannot be initialized with a value of type "int *"
testsub(xx);
^
1 error detected in the compilation of "test.cc"."
Why? Your help is appreciated.
Best wishes,
Ting
int* cannot be used where the argument type is const int* &.
Say you have:
const int a = 10;
void foo(const int* & ip)
{
ip = &a;
}
int main()
{
int* ip = NULL;
foo(ip);
*ip = 20; // If this were allowed, you will be able to
// indirectly modify the value of "a", which
// is not good.
}
As the error message says, the argument type is incompatible; the function wants a pointer to const int, while you supply a pointer to int.
If you're asking why that's incompatible: allowing it would allow you to break const-correctness, as in this example:
void testsub(const int* &xx ) {
static const int x;
xx = &x;
}
int* xx;
testsub(xx); // Shouldn't be allowed, because...
*xx = 666; // BOOM! modifying a constant object.
Maybe try this
void testsub(const int* xx );
int main ()
{
int xx [10];
testsub(xx);
}
void testsub(const int* xx){}
You don't need the &, because you are passing a pointer as argument.
When you forward a "C-Array" (your int[10]), you will have a pointer to the first element of this array in your function.
void testsub(const int* xx );
int main ()
{
int* xx;
xx= new int [10];
testsub(xx);
}
void testsub(const int* xx){}
I think you got confused by your book, because they always write something like "Call by reference". That doesn't mean to pass the parameter as a reference with the &.
Often it is useful to pass also the size of the array to the function ... so it would like:
void testsub(const int* xx, size_t arraySize);
int main ()
{
int* xx;
xx= new int [10];
testsub(xx, 10);
}
void testsub(const int* xx, size_t arraySize){}
Now you can access the array in your function and you have the possibility to check the index, if you want to access the array with an index.
void testsub(int* xx, size_t arraySize)
{
for(size_t i=0; i<arraySize; ++i)
// ^ this way you will never try to access
// memory, which does not belong to the array
// => no seg fault, or whatever happens
{
// do sth. with the array ... for example setting values to 0
xx[i] = 0;
}
}
This question already has answers here:
How to convert "pointer to pointer type" to const?
(2 answers)
Closed 9 years ago.
I have the very simple code in c++. When I compile under Visual studio, the error happens.
#include <stdint.h>
#include <time.h>
void func1(const uint8_t* data)
{
}
void func2(const uint8_t** data)
{
}
int main()
{
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);//OK
func2(data2);//error C2664: cannot convert argument 1 from 'uint8_t **' to 'const uint8_t **'
}
the full error meesage is:
error C2664: 'void func2(const uint8_t **)' : cannot convert argument 1 from 'uint8_t **' to 'const uint8_t **'
Usualy you cannot convert const XXX to XXX, but from XXX to const XXX should be OK, Why this error happens here?
but from XXX to const XXX should be OK
No, this isn't okay in this specific instance. Consider:
int const x = 10; // implementation stores to read-only memory
// implementation crashes on writes to read-only memory
void foo(int const **ptr) {
*ptr = &x;
}
int main() {
int *p;
foo(&p);
*p = 12; // crash
}
If this were legal it would assign a 'pointer to const' value to a 'pointer to non-const' object, and therefore enable dangerous writing to constant objects.
For a conversion to const to be okay const must be added at every level in the type above where the lowest const is added (except the very top).
For example it's not okay to convert int ****** to int ***const***, but it is okay to convert it to int ***const*const*const*. This also applies to volatile: you can convert int ****** to int ***volatile*const*const* but not int ***volatile***
This rule in the type system protects us from mistakenly treating const objects as non-const, or volatile objects as non-volatile, and if we really want to make this mistake then we have to use const_cast.
foo(const_cast<int const **>(&p));
*p = 12; // crash
With const cast the program is well formed and the compiler happily produces an executable that exhibits undefined behavior. (live example)
Fixing foo() to allow it to take a pointer to non-const:
void foo(int const * const *ptr) {
*ptr = &x; // error, can't modify *ptr
}
foo(&p); // conversion works fine
prevents foo() from writing a 'pointer to const' value into a 'pointer to non-const' object. (live example)
You probably got the idea that XXX to const XXX is okay because the most common case of this, i.e. with single level pointers: int * -> int const *, is okay and also obeys the above conversion rule. const at the very top level doesn't matter because changes to the parameter itself won't escape the function.
When you use const to pointer of pointer you need to use uint8_t const* const*
#include <stdint.h>
#include <time.h>
void func1(const uint8_t* data) {
}
void func2( uint8_t const* const* data ) {
}
int main() {
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);//OK
func2(data2);
}
Here are your two options, this...
void func1(const uint8_t* data)
{
}
void func2(const uint8_t** data)
{
}
int main()
{
const uint8_t* data1 = NULL;
const uint8_t** data2 = NULL;
func1(data1);
func2(data2);
}
Or this...
void func1(uint8_t* data)
{
}
void func2(uint8_t** data)
{
}
int main()
{
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);
func2(data2);
}