This question already has answers here:
constness and pointers to pointers
(4 answers)
non-const pointer argument to a const double pointer parameter
(1 answer)
Closed 8 years ago.
I want to pass argv to another function, and can do it with no problems when I define the function like this:
void function(char** argv);
and call it from main with:
function(argv);
However, I would like to keep everything const where possible (I don't actually plan to change argv, or the value of either of the pointers). My problem is that as soon as I add the keyword const anywhere to argv in the function declaration I get conversion errors, e.g. this code
void function(const char** argv);
gives the compile error:
error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
I've tried putting const in different places and get similar errors. Is there a way to pass argv while keeping the contents and pointers all constant?
Related
This question already has answers here:
Cannot convert from XXX** to const XXX** [duplicate]
(3 answers)
How to convert "pointer to pointer type" to const?
(2 answers)
Closed 4 years ago.
E.g. the following will fail to compile:
auto foo = [](const char**) {};
char* ptr = nullptr;
foo(&ptr);
Visual studio says that there's a conversion that loses qualifiers. Clang says cannot initialize a parameter of type 'const char **' with an rvalue of type 'char **". Perhaps my brain just isn't working today, but why is this dis-allowed? char* can implicitly convert to const char* after all
Oh wait, yes my brain isn't working today. foo can assign a const char* to the pointer, which is clearly bad.
This question already has answers here:
cannot convert 'std::basic_string<char>' to 'const char*' for argument '1' to 'int system(const char*)'
(6 answers)
Closed 6 years ago.
I tried to use system() in a c++ app
it works very well if i do it like:
system("notepad");
But it gives error when i try to do like:
cin >> cmdlol;
system(cmdlol);
Error:
cannot convert 'std::string {aka std::basic_string}' to 'const
char*' for argument '1' to 'int system(const char*)'|
cmdlol seemes to be std::string, which can't be converted to const char* implicitly. And std::system only accepts const char* as its argument, that's why compiler complains.
You could use std::basic_string::c_str() explicitly.
system(cmdlol.c_str());
And about why system("notepad"); works well, "notepad" is a string literal with type const char[8] (including null character), note it's not std::string and might decay to const char* when passed to std::system.
std::system wants a const char*, that's a C-style array.
To convert a std::string to a const char*, you can use the function c_str().
system(cmdlol.c_str());
This question already has answers here:
Why isn't it legal to convert "pointer to pointer to non-const" to a "pointer to pointer to const"
(5 answers)
Closed 7 years ago.
I know that const char * p means we can't change the value which is pointed by p through p.
Now I'm writing a function which will take the parameters of the function main. Meaning that this function will take a char **. So I write this function like this:
void func(const char **);.
But when I pass the parameter of main to it, I get an error:
error C2664: 'void func(const char **)' : cannot convert argument 1 from 'char **' to 'const char **'
I just want to initialize a const pointer with a non-const pointer. This should work. If we do the opposite thing, we should get some error. But now I don't know why I get this error.
I just want to initialize a const pointer with a non-const pointer. This should be work.
That's not what you're trying to do, no.
You're trying to initialise a non-const pointer to pointer to const char, with a non-const pointer to pointer to char. That is never performed implicitly. Why? It's well documented elsewhere because it's not completely intuitive to all but, in short, if converting char** to const char** were allowed, then const-correctness would be violated.
It's not the same as converting char** to char** const, which is what you think you're trying to do.
It's unfortunate that main's arguments do not already have const strewn about them. Sorry. Fortunately, you can work around it with a const_cast:
void foo(const char** argv) {}
int main(int argc, char** argv)
{
foo(const_cast<const char**>(argv));
}
This is one of those situations in which using const_cast to hack around pre-existing silliness, contrary to the wishes of the type system, is actually okay.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
c++ passing a const object reference to a function
void SpectrumAnalyserThread::calculateFFT(AnalogData &frame, const QByteArray &playbackBuffer)
{
fft->window(frame.data(),frame.size());
fft->fix_fftr(frame.data(), qFloor(log(frame.size()) / log(2)), 0);
for(int i = 0; i < m_numSamples; ++i)
{
m_output.push_back(frame[i]);
}
fft->fix_fftr(m_output.data(), qFloor(log(m_output.size()) / log(2)), 0);
const QByteArray ba((const char*)m_output.data(), sizeof(ushort));
const_cast<QByteArray &>(playbackBuffer);
playbackBuffer.append(ba);
m_output.clear();
calculateMagnitude(frame);
}
I get the following error:
error: passing 'const QByteArray' as 'this' argument of 'QByteArray& QByteArray::append(const QByteArray&)' discards qualifiers [-fpermissive]
If I make the function const then it throws errors at
m_output.clear(), m_output.push_back(), which is obvious but I need to clear the buffer so that when the function is called again previous data does not get appended.
If you want to modify playbackBuffer then you should take the parameter as a non-const parameter:
QByteArray &playbackBuffer
This is completely independent of whether the member function of SpectrumAnalyserThread is declared const (which it shouldn't be if it modifies this' internal state).
Note that this line has no effect. To use the result of a cast you must do something with it. A statement that is a cast alone just performs the conversion and then throws the result of that conversion away.
const_cast<QByteArray &>(playbackBuffer);
You could do something like below but it risks undefined behaviour and is an abuse of the contract you have with callers of your function where you say, by taking a const reference, that you're not going to modify playbackBuffer.
const_cast<QByteArray &>(playbackBuffer).append(ba);
The problem is at
playbackBuffer.append(ba);
You want to mutate playbackBuffer, so don't pass it as a const reference.
const_cast returned an object of type QByteArray& (it wiped off const from the original type) but you didn't do anything with that object - the type of the playbackBuffer didn't change - it remained const QByteArray&.
You can do two things:
1) call class method on a temporary unnamed variable of type QByteArray& returned by the cast operator:
const_cast<QByteArray &>(playbackBuffer).append(ba);
2) assign return value of the cast operator to the local variable of type QByteArray& (if you want to use it again to call non-const member functions):
QByteArray& playbackBufferNonConstRef = const_cast<QByteArray&>(playbackBuffer);
playbackBufferNonConstRef.append(ba);
Regardless of this, you should first think of why passing an object as a const reference and then trying to trick it and change it after casting const away. If you declare function's argument as a const reference, your clients will believe that object passed to it won't be changed. But with this design they'll be getting unexpected results...
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
why isnt it legal to convert (pointer to pointer to non-const) to a (pointer to pointer to a const)
I have a function:
bool isCirclePolygonIntersection(const Point*, const int*, const Point*,
const Point**, const int*);
and I'm trying to call it like this:
isCirclePolygonIntersection(p, &r, poly_coord, poly, &poly_size)
where poly defined like this:
Point** poly = new Point*[poly_size];
and there is a compiler error when I'm trying to compile it:
error C2664: 'isCirclePolygonIntersection' : cannot convert parameter 4 from 'Point **' to 'const Point **'
1> Conversion loses qualifiers
from what I've learned is that you cannot give const argument to function when a function expects a non const argument, but it's fine otherwise.
Does anyone knows what is the problem??
Thanks.
You're correct; you can implicitly convert a T * to a const T *. However, you cannot implicitly convert a T ** to a const T **. See this from the C FAQ: http://c-faq.com/ansi/constmismatch.html.
An implicit conversion from Point** to const Point** would open a hole in the type system, hence there is no such conversion in C++.
For details, see Why am I getting an error converting a Foo** → Foo const**?
Changing const Point** to const Point * const * will fix your problem.
By the way, why the additional indirection? That is, why do you use an array of pointers? I would suggest a std::vector<Point> instead. Or is Point a polymorphic base class?
Parashift has a great explanation on why this is prohibited:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17