How to initialize "unsigned char *" with default argument in C++? - c++

I have a class with a method with the following signature:
void print(unsigned char *word);
I need to set "" as default value for word, how can I do that?
I tried the obvious void print(unsigned char *word=""); but I got the following error:
error: cannot initialize a parameter of type
'unsigned char *' with an lvalue of type 'const char [1]'
void print(unsigned char *word="");
Since I can't initialize word with a string literal who should I do it?

You say that this is a "prefix" argument to apply to the printing.
The answer is that you should make the argument const, stop doing whatever mutations you're doing to it inside the function, and then use "" as a default argument:
void print(const char* prefix = "")

try
unsigned char empty[] = { 0 };
void print(unsigned char* word = empty )
{
...
}

"" yields an array of const char, whereupon you want an array of or pointer to NON-const unsigned char, both the type and the cv-qualification don't fit.
Note also that in C++ char != signed char and char != unsigned char.
Possibly you mean void print(const char *word);, but probably you want just print(std::string const &) or print(std::string).

void print();
void print(unsigned char* prefix);
// in cpp file:
void print(){
unsigned char temp = 0;
print(&temp);
}
This provides two overloads, one with 0 and one eith one argument.
The zero argument one has some automatic storage memory it provides to the one argument one. Note that only the single byte under the pointer is valid to read/write: without a length, print has no way to know any different anyhow.
While there is no array, none is needed for a single element.

Related

C++ pointer to pointer of array

how to pass array to this function ?
this is the function :
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
it is done by this and it works
unsigned char X[5] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
why I need *pointertoX ?
is there any other way for do this ?
whole code :
#include <iostream>
using namespace std;
void fire(const uint8_t *const s[])
{
cout<<*s<<endl;
}
int main() {
unsigned char X[10] = {255,255,255,255};
unsigned char *pointertoX ;
pointertoX = X;
fire(&pointertoX);
return 0;
}
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
https://ffmpeg.org/doxygen/4.1/group__libsws.html#gae531c9754c9205d90ad6800015046d74
this is the function :
void fire(const uint8_t *const s[])
That function accepts a pointer to a const pointer to a const uint8_t.
and I want to pass this array to that :
unsigned char X[10] = {255,255,255,255};
You cannot.
In order to pass an array into a function that accepts a pointer, the function would have to accept a pointer to element type of that array (after other implicit conversions such as pointer from to non-const into pointer to const). The element of that array is unsigned char, while the function accepts a pointer to a const pointer to a const uint8_t.
why I need *pointertoX ?
Because the function accepts a pointer to a const pointer to a const uint8_t, and &pointertoX is a pointer to a pointer to an unsigned char. Given that uint8_t is an alias of unsigned char, &pointertoX is implicitly convertible to the function parameter.
note : I'm trying to pass bitmap to ffmpeg "sws_scale" ..
Read the documentation carefully:
srcSlice the array containing the pointers to the planes of the source slice
dst the array containing the pointers to the planes of the destination image
You're trying to pass an array of characters into a function that expects an array of pointers.
P.S. The behaviour of the program is undefined because *s does not point to a null terminated string, but you insert it into a character stream which has such requirement.

How to declare a pointer to pointer to constant in C++?

I'm trying to write a function to parse command line arguments. This is the function declaration:
void parse(int, char const **);
Just in case, I have also tried (const char)**, const char **, and cchar ** using a typedef const char cchar. However, all of these (as expected, since they should all be identical) result in an error if I pass a char ** into the function, as in:
void main(int argc, char **argv) {
parse(argc, argv);
The error I get from GNU's compiler is error: invalid conversion from 'char**' to 'const char**' and the one from Clang is candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument.
I have seen such solutions suggested as declaring a pointer to a const pointer to char (const char * const *), but I don't want either pointer to be const because I want to be able to modify the pointer so I can iterate over an argument using for(; **argv; ++*argv). How can I declare a "non-const pointer to non-const pointer to const char"?
The function should be declared as:
void parse(int, char const * const *);
In C++, char ** can implicitly add const at all pointer depths, so you can call it as parse(argc, argv).
In C, const can only be added at the first pointer depth (this is a design defect in the language). Here is a dedicated thread. So you have to call the function as: parse(argc, (char const * const *)argv); unfortunately.
The safest signature that prevents modification of the arguments whilst allowing any other const combination to call the function is this:
parse(int argc, char const* const* argv);
That means that argv is a pointer to a const pointer to a const char
You can happily iterate over the parameters like this:
for(auto arg = argv + 1; *arg; ++arg)
{
if(!std::strcmp(*arg, "--help"))
return print_help();
else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
verbose_flag = true;
// ... etc...
}
Notice there is no need to accept the variable int argc because the array of character arrays is null terminated.
So I normally use this:
struct config
{
// program options and switches
};
config parse_commandline(char const* const* argv);

How to get a const char* function to work?

So I have this char const* blahblahblah(const char* s) function but when I try to use strcat(s, " ") or return s[k]in it it says
const char*s
Error: argument of type "const char*" is incompatible of parameter of type "char"
If I want the function to stay as is what should I change in my parameters in order for it to work?
If you declare const char* s, then you should not write strcat(s, " "), because strcat modifies s.
if you declare char const* reverseWordsOnly, then why do you return s[k]? s[k] is not a pointer.
EDIT:
This depends on what you want to do. I don't know what you want to do in this function.
If you don't modify s, then declaring const char* s is OK.
If you want to return char const *, then maybe you want to return &s[k] instead of s[k].
Maybe you want to return char *, then you can cast &s[k] using (char *)&s[k].
It's because the const on the left-hand-side of the * means that what's pointed to is immutable: strcat obviously needs to alter its parameter. And s[k] will refer to a char, not any sort of char *.

char pointers, char arrays, and strings in the context of a function call

What is the difference between the line that does not compile and the line that does compile?
The line that does not compile gives this warning: deprecated conversion from string constant to 'char*'
Also, I'm aware casting (char *) on the string being passed in to the function would solve the problem, but I would like to understand why that's even necessary when the 2nd line compiles just fine.
class Student {
public:
Student( char name[] ) {
}
}
int main() {
Student stud( "Kacy" ); //does not compile
char name[20] = "Kacy"; //compiles just fine
}
The char[] signature in the parameter is exactly the same as char*. In C++, it is illegal to convert a string constant char const* (the string "Kacy") to a char* because strings are immutable.
Your second example compiles because the name is an actual array. There is no change to char*.
As a solution, change your parameter to take a const string array:
Student(char const name[]);
which again is the same as
String(char const *name);
though you're better off using std::string:
#include <string>
class String
{
public:
String(std::string name);
};
C++ string literals have type "array of n const char", which decays into const char * in your use case. The implicit conversion to char * (that is, discarding the const) you're trying is deprecated, so there's a warning. Change the type in the constructor's signature or make an explicit const-cast.
From the C++ standard:
An ordinary string literal has type "array of n const char" and static storage duration
The string
"Kacy"
is not an array of characters when the compiler produces the code. Instead, it will stash the string "Kacy" somewhere in memory, and produce a pointer to that place. So what you get is a const char * pointing at the string "Kacy\0".
If you change your constructor to:
Student(const char *nmae)
you can use it both as:
Student stud("Kacy");
and as this:
char name[20] = "Kacy";
Student stud2(name);
Note here that the compiler will generate code to FILL the array name with the characters in "Kacy", which is different from just usinv "Kacy" as an argument to the Student constructor.

Deprecated conversion from string constant to char * error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ deprecated conversion from string constant to ‘char*’
I am having following code, though i didn't copy full code because it is huge.
Following code is in template class, and i am getting warning as below. Because of warning in template i am not able to instantiate it and getting "instantiated from here" error.
warning: deprecated conversion from string constant to 'char*''
void ErrorMessageInRaphsodyCode(char* pcCompleteMessage, char* pcMessage, char* pcFileName, unsigned int RowNo)
{
//...
}
char cCompleteMessage[200];
memset(cCompleteMessage, 0x00, sizeof(cCompleteMessage));
char*cMessage = "add reorgenize failed";
ErrorMessageInRaphsodyCode(cCompleteMessage, cMessage, "omcollec.h", __LINE__);
My question is what is best way to get rid of above warning ?
If a function takes a char const *, it guarantees that it only reads whatever data the pointer points to. However, if it takes a non-const pointer, like char *, it might write to it.
As it is not legal to write to a string literal, the compiler will issue a warning.
The best solution is to change the function to accept char const * rather than char *.
char cMessage[] = "add reorganize failed";
This should get rid of the warning.
Best way to get rid of it is to fix the function that is taking the parameter.
If your code is correct and the function does indeed take string constants, it should say so in its prototype:
void ErrorMessageInRaphsodyCode(char* pcCompleteMessage, char* pcMessage, const char* pcFileName, unsigned int RowNo)
If you can't do that (you don't have the code), you can create an inline wrapper:
inline void ErrorMessageInRaphsodyCodeX(char* p1, char* p2, const char* p3, unsigned int p4)
{ ErrorMessageInRaphsodyCode(p1,p2,(char*)p3,p4); }
and use the wrapper instead.
If your code is incorrect and the function does actually require writeable memory (which I highly doubt), you will need to make the string writeable by either creating a local array as Jan suggested, or mallocating enough memory.
(1) Make the variable a const char*
(..., const char* pcFileName, ...)
(2) If above is not possible and you want to retain the state of char* and const char* then make the function a template:
template<typename CHAR_TYPE> // <--- accepts 'char*' or 'const char*'
void ErrorMessageInRaphsodyCode(char* pcCompleteMessage, CHAR_TYPE* pcMessage, char* pcFileName, unsigned int RowNo)
{
//...
}
function c_str() of std::string class.