I try to implement source code as below:
bool getParam(char* cmd, char** prm_arr, int num)
{
}
void main()
{
char strC[] = "btOK,btCancel";
char foo[10][10];
bool res = getParam(strC,foo,2);
}
It shows error:
error: cannot convert ‘char (*)[10]’ to ‘char**’ for argument ‘2’ to ‘bool getParam(char*, char**, int)’
bool res = getParam(strC,foo,2);
I think char** and char (*)[10] is similar in this case, isn't it?
The array declared like
char foo[10][10];
is converted to the type char( * )[10] when is passed to the function. And there is no implicit conversion from the type char ( * )[10] to the type char *.
So the function declaration should be
bool getParam(char* cmd, char ( *prm_arr )[10], int num);
That is in expressions with rare exceptions arrays are converted to pointers to array elements type.
If you have an array of the type T as for example
T a[N];
when the array is converted to the type T *.
In the declaration of the array foo the type of its elements is char[10]. So the array is converted to pointer to the element type char ( * )[10]
Pay attention to that the function main shall be declared like
int main()
instead of
void main()
Related
I am currently working with a C-API (OpenSSL) and there are a lot functions declared like the following:
// From bytes to TYPE
TYPE *d2i_TYPE(TYPE **a, unsigned char **ppin, long length);
// From TYPE to bytes
int i2d_TYPE(TYPE *a, unsigned char **ppout);
But sometimes, functions expect a pointer to an array of pointers to some const type:
// From bytes to TYPE
TYPE *d2i_TYPE(TYPE **a, const unsigned char **ppin, long length);
Notice the const unsigned char ** vs unsigned char ** and ignore the functions' first argument.
Now consider the following example, where some input data is given as non-const pointers. What is the correct way of casting the array of pointers to an array of pointers const? And also, since the function expects a pointer, the parameter must be an lvalue. I am guessing this is the reason there is no implicit cast..
int length = 42;
unsigned char * data = new unsigned char[length];
// Error C2664: cannot convert argument 2 from 'unsigned char **' to 'const unsigned char **'
TYPE * my_typeE = d2i_TYPE(nullptr, &data, length);
// My solution:
auto x = reinterpret_cast<unsigned char const *>(data);
auto y = const_cast<unsigned char const *>(data);
TYPE * my_typeX = d2i_TYPE(nullptr, &x, length);
TYPE * my_typeY = d2i_TYPE(nullptr, &y, length);
Are there other solutions that are possibly easier to read?
No need of cast:
const unsigned char* z = data;
[[maybe_unused]]TYPE * my_typeZ = d2i_TYPE(nullptr, &z, length);
Demo
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);
When building my C++ application the build fails at this line of code
if (!PyTuple_GetByte(poArgs, 0, &SourceCell.window_type))
with this error
error C2664: 'PyTuple_GetByte' : cannot convert parameter 3 from
'char *' to 'unsigned char *'
This is the called function:
bool PyTuple_GetByte(PyObject* poArgs, int pos, unsigned char* ret);
The third parameter &SourceCell.window_type is type char.
Is there a way to convert/cast the parameter inside the function call like
if (!PyTuple_GetByte(poArgs, 0, reinterpret_cast<unsigned char*>(&SourceCell.window_type)))
or do I have to deal with it in another way?
From the error, the signature of the PyTuple_GetByte function was expecting a third parameter of type unsigned char*, but you passed a variable of type char* at its invocation. I think you have two options here.
You can change the signature of function PyTuple_GetByte to expect a char* parameter.
You need to convert your input variable from type char* to type unsigned char*, before you can pass it into PyTuple_GetByte.
The conversion is normally like this:
unsigned char* convert_var = reinterpret_cast<unsigned char*>(&SourceCell.window_type); // (c++ way)
or
unsigned char* convert_var = (unsigned char*)(&SourceCell.window_type); // (c way)
I have this function
unsigned char NCN_System_upload(unsigned char *data, unsigned char len);
I have an array defined as such:
unsigned char data[3];
I'm using the function as the following:
NCN_System_upload(&data, 3);
However, I get the following error:
argument of type unsigned char (*)[3] is incompatible with parameter of type unsigned char*
Why doesn't this work?
The name of the array is already (can be implicitly converted) to a pointer to its beginning. Thus, you should do it like this:
NCN_System_upload(data, 3);
I receive this error:
array.cpp: In function ‘void strcat2(char*, const char*)’:
array.cpp:74: error: invalid conversion from ‘char’ to ‘char*’
array.cpp:74: error: initializing argument 1 of ‘void strcpy2(char*, const char*)’
array.cpp:74: error: invalid conversion from ‘char’ to ‘const char*’
array.cpp:74: error: initializing argument 2 of ‘void strcpy2(char*, const char*)’
When trying to run this code:
//Concatenates two arrays of characters using pointers
void strcat2(char* t, const char* s)
{
unsigned int i;
for (i = 0; *t; i++);
strcpy2(*(t + i), *s);
}
Here is the strcpy2 function it calls:
//Copies the information from one array of characters to another using pointers
void strcpy2(char* t, const char* s)
{
for ( ; *t++ = *s++;);
}
It says invalid conversion from char to char*, but where am I trying to convert from char to char*? It seems to me that everything in the code is char*. What am I missing?
I've looked over this code many times and can't seem to find what is wrong. I'm relatively new to pointers, go easy! Thank you very much for any help!
*(t + i)
t is of type char *.
so t + i means char * + i which means "add the value of i to the pointer to make a new pointer". *(t + i) then dereferences that new pointer, the type of that dereferenced expression will be char. So yes, the compiler is correct. You're trying to pass a char into a function that expects a pointer-to-char.
You simply want
strcpy2(t + i, s);
note: You were also dereferencing s, which would cause the same compile error.
The expression *(t + i) in strcpy2(*(t + i), *s); is a char type because the * dereferences the pointer.
Change these statements
for (i = 0; *t; i++);
strcpy2(*(t + i), *s);
to
for (i = 0; *(t + i ); i++);
strcpy2( t + i, s);
Also it would be better to declare the functions as having return type char *. For example
char * strcat2(char* t, const char* s);