bool potezn(int x,int y,int k,char c,char ram1[][100],bool segfault,int n,int m)
{
segfault=true;
if(c=='U' && x>=k){x=x-k;segfault=false;}
if(c=='D' && x+k<n){x=x+k;segfault=false;}
if(c=='L' && y>=k){y=y-k;segfault=false;}
if(c=='R' && y+k<m){y=y+k;segfault=false;}
if(ram1[x][y]=='.')ram1[x][y]='N';//zauzima polozaj ukoliko moze
return segfault;
}
segfault=potezn(x,y,q,c,ram,segfault,n,m);
This is my code,and when i run it,i keep getting error
D:\dev\Dev-Cpp\segfault2.cpp
cannot convert char (*)[((unsigned int)((int)m))] to char (*)[100] for argument 5 to bool potezn(int, int, int, char, char (*)[100], bool, int, int)
Help please,
Thanks in advance
The reason you are getting that compile error is because the type of ram that you are trying to call the function potezn with is not the type potezn wants.
Take a careful look at ram.
Its type must be char*[100], not char(*)[((unsigned int)((int)m)]].
You can either declare ram's length explicitly, or change char ram1[][100] to char * ram1. (Also consider using std::vector. std::vector is an array that manages its length automatically for you.)
void Foo(char ram[][100]);
void Bar(char * ram); // Treat the ram as one long chunk array.
int main()
{
char ram[5][100];
char ram_error[5][5];
Foo(ram); // Ok.
Foo(ram_error); // Error.
Bar(reinterpret_cast<char *>(ram_error)); // Ok. Not recommended.
return 0;
}
Related
What does this error message mean?
error: call of overloaded ‘setval(int)’ is ambiguous
huge.cpp:18: note: candidates are: void huge::setval(unsigned int)
huge.cpp:28: note: void huge::setval(const char*)
My code looks like this:
#include <iostream>
#define BYTES 8
using namespace std ;
class huge {
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
void setval(const char *);
};
void huge::setval(unsigned int t) {
for(int i = 0; i< BYTES ; i++) {
data[i] = t;
t = t >> 1;
}
}
void huge::setval(const char *s) {
for(int i = 0; i< BYTES ; i++)
data[i] = s[i];
}
int main() {
huge p;
p.setval(0);
return 0;
}
The literal 0 has two meanings in C++.
On the one hand, it is an integer with the value 0.
On the other hand, it is a null-pointer constant.
As your setval function can accept either an int or a char*, the compiler can not decide which overload you meant.
The easiest solution is to just cast the 0 to the right type.
Another option is to ensure the int overload is preferred, for example by making the other one a template:
class huge
{
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
template <class T> void setval(const T *); // not implemented
template <> void setval(const char*);
};
The solution is very simple if we consider the type of the constant value, which should be "unsigned int" instead of "int".
Instead of:
setval(0)
Use:
setval(0u)
The suffix "u" tell the compiler this is a unsigned integer. Then, no conversion would be needed, and the call will be unambiguous.
replace p.setval(0); with the following.
const unsigned int param = 0;
p.setval(param);
That way it knows for sure which type the constant 0 is.
Use
p.setval(static_cast<const char *>(0));
or
p.setval(static_cast<unsigned int>(0));
As indicated by the error, the type of 0 is int. This can just as easily be cast to an unsigned int or a const char *. By making the cast manually, you are telling the compiler which overload you want.
Cast the value so the compiler knows which function to call:
p.setval(static_cast<const char *>( 0 ));
Note, that you have a segmentation fault in your code after you get it to compile (depending on which function you really wanted to call).
That is ambiguous because a pointer is just an address, so an int can also be treated as a pointer – 0 (an int) can be converted to unsigned int or char * equally easily.
The short answer is to call p.setval() with something that's unambiguously one of the types it's implemented for: unsigned int or char *. p.setval(0U), p.setval((unsigned int)0), and p.setval((char *)0) will all compile.
It's generally a good idea to stay out of this situation in the first place, though, by not defining overloaded functions with such similar types.
I am trying to pass a multidimensional array to a function. When I try to compile I an getting an error saying
[Error] cannot convert 'int (*)[3]' to 'int (*)[2]' for argument '1' to 'void reve(int (*)[2], int)'
What is the problem ? What am I doing wrong? Following is the code I wrote.
#include <iostream>
using namespace std;
const int rows=2;
const int cols=2;
const int n = 3;
void reve(int arr[rows][cols],int n){
int br[3][3],i,j,k,l;
for(i=n-1,k=0;i>=0,k<n;i--,k++){
cout<<endl;
for(j=n-1,l=0;j>=0,l<n;j--,l++)
br[k][l]=arr[i][j];
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
arr[i][j]=br[i][j];
}
}
int main() {
int i,j,k,l,ar[3][3],br[3][3];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
cin>>ar[i][j];
int n=3;
reve(ar,n);
for(i=0;i<3;i++){
cout<<endl;
for(j=0;j<3;j++)
cout<<ar[i][j];
}
return 0;
}
When you use a 2-d array in a function call, it decays into a pointer type. However, all dimensions but the first one must match exactly.
If the argument type of a function is int (*arg)[2], then, you can't use a variable that is declared as int var[3][3] to call the function. var decays to a pointer whose type is int (*)[3].
It is confusing at first because it seems to work in case of 1-d arrays.
void foo(int arg[10])
{
}
int var[2];
foo(var); // OK
That's because the compiler ignores the size of the first dimension of the array. The above definition of foo is same as:
void foo(int arg[])
{
}
and
void foo(int* arg)
{
}
However, for a multidimensional array, the size of all but the fist dimension must match exactly. Otherwise, they are different types.
The reve() function expects an array of [2][2] but you're passing a [3][3] array.
The ar array in main() is declared as int ar[3][3] while it should have been int ar[rows][cols]
You have reserved 2 blocks in memory. And in your loop, you are taking it from 2 to 0 that makes it 3. Do the following changes.
const int n= 2;
And it should work for your program.
void qsort (void* base, size_t num, size_t size,
int (*compare)(const void*,const void*));
Why does the qsort function want an int* return type for compare when the compare function is of type int?
int compare (const void * a, const void * b)
{
if ( *(MyType*)a < *(MyType*)b ) return -1;
if ( *(MyType*)a == *(MyType*)b ) return 0;
if ( *(MyType*)a > *(MyType*)b ) return 1;
}
Can someone explain this please, my program wont compile because of this. Thanks!
Code taken from this source:
http://www.cplusplus.com/reference/cstdlib/qsort/
It is not returning an int *, it is returning an int. compare is a function pointer. The * you are seeing there defines it as a function pointer. (Note the parentheses around *compare.)
cdecl parse of int (*compare)(const void*,const void*)):
declare compare as pointer to function (pointer to const void, pointer to const void) returning int
This would be the parameter declaration if it were a pointer to a function returning an int *:
int * (*compare)(const void*,const void*))
If your code is not compiling then it is for some other reason. Consider adding the error message to your question (or creating a new question) if you would like more specific advice about the compiler error.
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
The return type is void* and proto_type is the name of the function? Or is this a pointer to function? Which are the parameters:
(long int, char *b) or this (const char *b, unsigned short int d)
Please, explain how this function works.
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
This is a function declaration. The function name is proto_type, which takes two parameters of types:
long int
char *
and returns a pointer to a function which takes
const char*
unsigned short int
and returns void*.
Now if you use typedef, all of the above will becomes obvious:
typedef void* function_type(const char *b, unsigned short int d);
function_type* proto_type(long int, char *b);
Hope that helps.
This declares proto_type as function taking (long int, char *) and returning pointer to a function taking a (const char *, unsigned short int) and returning a void pointer.
In other words:
typedef void * (*R)(const char *, unsigned short int); // return type
R proto_type(long int, char *);
I suggest bookmarking www.cdecl.org for the questions of this type. Beware, the page is a bit picky about what you type in (it doesn't accept parameter names at least).
Start with the name of the function, then evaluate that using
the usual expression syntax. Thus:
proto_type // proto_type
proto_type( long, char* ) // is a function taking long, char*
// (since function call has precedence over *
*proto_type( long, char* ) // returning a pointer
(*proto_type(...)) // (no change, but necessary for precedence reasons)
(...)( char const*, unsigned short )
// to a function taking char const*, unsigned short
*(...)(...) // returning pointer
void *(...)(...) // to void
(It's a little harder in cases where you don't have the name,
like the type in a static_cast.)
I will explain my process for parsing complex c-style declarations. I hope you will find it useful.
C-style parsing can be thought of as a right-to-left parsing starting at the identifier and bounded by parenthesis. So we start at the identifier proto_type
// vvvvvvvvvv-------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
As we can see, moving right from proto_type, we immediately see a function call and some parameters, so that's easy. proto_type is a function that takes a long int and char* as parameters.
// v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Here we hit the first bounding parentheses, so we have to go backwards to find the next token which is here:
// v----------------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
So now we know it returns a pointer to something. Now we have to look to the right again to find out what because of the bounding parentheses again
// v--------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
Since we found another function call operator, the pointer it returns must be a pointer to a function that takes a const char* and an unsigned short int.
Finally, we reached another bounding parentheses, so move back left to find the return value of that function pointer.
//vvvv----------------------------------------------------------------------v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
The function pointer returns a void* as the return value.
So to recap in English: proto_type takes a long int and a char* as parameters and returns a pointer to a function that takes a const char* and unsigned short int as parameters and returns a void*.
proto_type is a function, which takes two arguments, long int and char *. It returns a function pointer that takes two arguments of type const char * and unsigned short int.
And to write this without using typedef is not very kind to the reader.
Using VS2012 on Windows 8 x64.
proto_type is a function that takes a long int (which is unnamed) and an unsigned short int d, and returns a function of the form void * proto2(const char *b, unsigned short int d);
Here's some working code:
#include <stddef.h>
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
void * proto2(const char *b, unsigned short int d);
int main(int argc, char** argv){
if(proto_type(0, NULL)(NULL, 0) != (void*)8675309)
return 0;
else
return 1;
}
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d){
return &proto2;
}
void* proto2(const char *b, unsigned short int d){
return (void*)8675309;
}
What's going on is that main calls proto_type which returns a pointer to proto2, which main immediately calls. proto2 returns a magic pointer value that we check against in main.
Here's the debug output from VS2012:
The program '[3188] test.exe' has exited with code 1 (0x1).
As for "how this function works", the answer is however you want it to (assuming you're the one implementing it).
If you want another way to look at it, you want to read it inside to out for the order of which functions are called.
The lesson here is that C(++) function pointers are immensely opaque.
I have done what #Tomek said and copied your prototype to http:www.cdel.org and then removed the parameter names from the prototype as:
void * (*proto_type(long int, char *)) (const char *, unsigned short int );
pressed enter, and the web site returned:
declare proto_type as function (long int, pointer to char) returning pointer
to function (pointer to const char, unsigned short int) returning pointer
to void
Now, to translate this into carbon-unit speak: proto_type is declared as a function that takes a long int and a pointer to a char as parameters, it returns a pointer to a function that takes a pointer to a const char and an unsigned short integer and that function returns a void pointer.
Finally, a void pointer can be cast into a pointer to any other data type.
What does this error message mean?
error: call of overloaded ‘setval(int)’ is ambiguous
huge.cpp:18: note: candidates are: void huge::setval(unsigned int)
huge.cpp:28: note: void huge::setval(const char*)
My code looks like this:
#include <iostream>
#define BYTES 8
using namespace std ;
class huge {
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
void setval(const char *);
};
void huge::setval(unsigned int t) {
for(int i = 0; i< BYTES ; i++) {
data[i] = t;
t = t >> 1;
}
}
void huge::setval(const char *s) {
for(int i = 0; i< BYTES ; i++)
data[i] = s[i];
}
int main() {
huge p;
p.setval(0);
return 0;
}
The literal 0 has two meanings in C++.
On the one hand, it is an integer with the value 0.
On the other hand, it is a null-pointer constant.
As your setval function can accept either an int or a char*, the compiler can not decide which overload you meant.
The easiest solution is to just cast the 0 to the right type.
Another option is to ensure the int overload is preferred, for example by making the other one a template:
class huge
{
private:
unsigned char data[BYTES];
public:
void setval(unsigned int);
template <class T> void setval(const T *); // not implemented
template <> void setval(const char*);
};
The solution is very simple if we consider the type of the constant value, which should be "unsigned int" instead of "int".
Instead of:
setval(0)
Use:
setval(0u)
The suffix "u" tell the compiler this is a unsigned integer. Then, no conversion would be needed, and the call will be unambiguous.
replace p.setval(0); with the following.
const unsigned int param = 0;
p.setval(param);
That way it knows for sure which type the constant 0 is.
Use
p.setval(static_cast<const char *>(0));
or
p.setval(static_cast<unsigned int>(0));
As indicated by the error, the type of 0 is int. This can just as easily be cast to an unsigned int or a const char *. By making the cast manually, you are telling the compiler which overload you want.
Cast the value so the compiler knows which function to call:
p.setval(static_cast<const char *>( 0 ));
Note, that you have a segmentation fault in your code after you get it to compile (depending on which function you really wanted to call).
That is ambiguous because a pointer is just an address, so an int can also be treated as a pointer – 0 (an int) can be converted to unsigned int or char * equally easily.
The short answer is to call p.setval() with something that's unambiguously one of the types it's implemented for: unsigned int or char *. p.setval(0U), p.setval((unsigned int)0), and p.setval((char *)0) will all compile.
It's generally a good idea to stay out of this situation in the first place, though, by not defining overloaded functions with such similar types.