I have problem with code from book:
const int SQUARE_ARRAY_SIZE = 4;
const int SQUARE_INFO_SIZE = 4;
typedef Square SquareArray[SQUARE_ARRAY_SIZE];
typedef SquareArray SquareInfo[SQUARE_INFO_SIZE];
SquareArray RedGeneric = { Square(0, 0), Square(0, 1),
Square(1, 1), Square(1, 0) };
SquareInfo RedInfo = { &RedGeneric, &RedGeneric, \\problem here
&RedGeneric, &RedGeneric };
It yells:
error C2440: 'initializing' : cannot convert from 'SquareArray (*)' to 'Square'
IntelliSense: no suitable constructor exists to convert from "SquareArray *" to "Square"
As I understand SquareInfo stands for array of SquareArray but it seems like vs2013 wants to break it to Squares and as result
SquareInfo m_squareInfo; ...
SquareArray* pSquareArray = m_squareInfo[m_iDirection];
yells:
IntelliSense: a value of type "const Square *" cannot be used to initialize an entity of type "SquareArray *"
Book is from 2008 and I don't know if it worked back then or there is error from beginning. As for q please tell me what's really wrong and how to make it work.
I'm fairly sure that the book meant to write
typedef SquareArray* SquareInfo[SQUARE_INFO_SIZE];
// ^
i.e., SquareInfo is an array of pointers to SquareArrays, rather than an array of SquareArrays. This is consistent with initializations using &RedGeneric and SquareArray* pSquareArray = m_squareInfo[m_iDirection];.
Looks like your book has a typo on that line
typedef SquareArray SquareInfo[SQUARE_INFO_SIZE];
When I make this to be a pointer
typedef SquareArray* SquareInfo[SQUARE_INFO_SIZE];
// ^
the code compiles fine.
Related
Here is an example of what I mean (I am using VS 2022 with C++11):
// Printing function: does not modify any array member, so everything should be const
void PrintArray(int const*const (&ct)[3])
{
printf("ct: x%p, {%u, %u, %u}\n",
&ct, ct[0] ? *ct[0] : 0, ct[1] ? *ct[1] : 0, ct[2] ? *ct[2] : 0);
}
int main(int argc, unsigned short* argv[])
{
// At some point: declare (and use) a modifiable array
int a = 1, b = 2, c = 3;
int* t[3] = {&a, &b, &c};
// At some later point: want to use the array without modifying it,
// then lets try some conversions
int* (&u)[3] = t; // OK - Same type conversion
int*const (&v)[3] = t; // OK - adding first constness on array elements
int const*const (&w)[3] = t; // FAIL: adding both constnesses on elements:
// error C2440 "cannot convert from 'int *[3]' to
//'const int *const (&)[3]" (ON VS 2022 C++ 11)
int const*const (&x)[3] = const_cast<int const*const(&)[3]>(t);
// FAIL: same error C2440
int const*const (&y)[3] = reinterpret_cast<int const*const(&)[3]>(t);
// OK - but annoyingly verbose and source of casting
// errors
// Of course the same problem happens for passing through functions call
PrintArray(t); // FAIL
PrintArray(reinterpret_cast<int const*const(&)[3]>(t)); // OK... but still annoying !
return 0;
}
OK, we know that reinterpret_cast is working, so I have a workaround here. So my question is more theoritical about C++ language:
Does someone know if the implicit conversion compiles on other compilers, like gcc ?
Does someone know if the C++ standard forbid this failing implicit conversion ?
And mostly, if the standard does forbid it, WHY ??? I KNOW that const conversions can lead to const/unconst inconsistencies sometimes. E.g. would have been the case if converting t to int const* (&)[3] because we could have added a const int into an array that is not const at the begining. But, in my example above, everything is const so I cannot find any weakness. Does someone see one ? Or is it just because it was too complex at the time for compilers to assert the rightness of the conversion ?
(Additional question for the braves: why cons_cast is failing here while it is only a constness casting ?)
These questions are for my C++ culture, I am open to all your analysis :)
Kind regards to everybody.
Hello to all the handsome people who want to save me from my pain,
I am new to c++, and after having done the usual intro stuff like strings, loops, arrays, pointers that w3schools tells you, I decided to write some code. I decided to start with a simple challenge that asks you to write some loops that will sort a few ints from highest to lowest or the other way around, without using the sort function(I was told there was something like this).
And the code is still not working. But this is normal for me as long I can understand why is it not working. (Pls don't answer why it doesn't work, just continue reading)
#include <iostream>
using namespace std;
int age[4] = { 26, 14, 6, 43};
int num = 4;
int a = 0;
double previous = 0;
int chosen = age[a];
void first() {
while (result[0] || result[num] == 0){
for (int i = 0; a != num; i++) {
chosen = age[a];
previous = age[i];
if (chosen < (previous + 0.01) ) {
chosen = result[a];
a++;
previous = age[0];
i = 0;
}
}
}
}
void last()
{
for (int i = 0; i < num; i++) {
cout << result[i] << "\n";
}
}
int main() {
first();
last();
}
So I tried to see if my main "if statement" was properly working and I added an already assigned value of result[0] where the variables were introduced.
int a = 0;
double previous = 0;
result[0] = 20;
int chosen = age[a];
And then when I ran the program this errors occurred:
error C2466: cannot allocate an array of constant size 0
(18,14): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(18,16): error C2440: 'initializing': cannot convert from 'int' to 'int [0]'
(18,12): message : There are no conversions to array types, although there are conversions to references or pointers to arrays
(line 18 is where I assigned result[0])
When I saw this I was like "I guess I am stupid enough and I don't know how to assign arrays", but then I checked if this was the case and I think this is not the case.
And then I understood the first error because I tried changing result[0] to result[4] and it disappeared, but I had no idea what the second error was saying.
So, as one wise man probably said, "If you have coding problems that google cannot answer, go to stack overflow".
And so I did. But the article I found was with code that was equal to my knowledge of Chinese. And if you are still wondering, I do not know a single Chinese word. And I didn't find a better article that could explain how to fix the problem in pure coding for beginners. I just started coding c++ in the pandemic and I don't understand anything other than English yet.
And I would really appreciate if someone could tell me what does this error mean and how is it possible to disappear with his other error friends waiting below him.
You haven't declared result. C has the idea that using an undeclared variable causes the compiler to assume that the variable is declared extern int. Some C++ compilers support this for backwards-compatibility, but it's not part of standard C++.
In this case, the compiler seems to support this so it assumes extern int result; since it hasn't seen a declaration for this name.
This results in two diagnostics:
The compiler is warning you about the "default int" declaration and that this is deprecated: "missing type specifier - int assumed"
Then the compiler is telling you that you can't subscript an int (result[0] makes no sense if result is an int): "cannot convert from 'int' to 'int [0]'"
Add an array declaration for result to fix this.
Look at the simple code below:
int main()
{
int a;
a = SDL_Init(SDL_INIT_JOYSTICK);
a = SDL_NumJoysticks();
for (int i=0; i<a; i++)
cout << SDL_JoystickName(i);
return 0;
}
I'm using SDL library, It seems there is nothing wrong with the code, I'm trying to get names of connected joysticks but It gives me the error below:
error C2664: 'SDL_JoystickName' : cannot convert parameter 1 from 'int' to 'SDL_Joystick *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Where is the problem?
The documentation states that SDL_JoystickName takes a SDL_Joystick* as parameter (The compiler says the same)
You can retrieve the SDL_Joystick* via SDL_JoystickOpen which takes an int as parameter.
see https://wiki.libsdl.org/SDL_JoystickName
EDIT: As Joachim Pileborg said, if you just want to retrieve the names, SDL_JoystickNameForIndex is the way to go
I found this code in the rendering library for Quake 3. There is this function:
void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap );`
It is being called in a loop somehwere else like this:
R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex, qfalse );
The weird part is that poly was declared as srfPoly_t *poly. What is going on
here? It is casting a srfPoly_t object to (void *) and then entering the
function as a surfaceType_t object.
Here are the declaration for the relevant structs:
typedef enum {
SF_BAD,
SF_SKIP, // ignore
SF_FACE,
SF_GRID,
SF_TRIANGLES,
SF_POLY,
SF_MD3,
SF_MD4,
SF_FLARE,
SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity
SF_DISPLAY_LIST,
SF_NUM_SURFACE_TYPES,
SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int )
} surfaceType_t;
typedef struct srfPoly_s {
surfaceType_t surfaceType;
qhandle_t hShader;
int fogIndex;
int numVerts;
polyVert_t *verts;
} srfPoly_t;
This is working in C, but I am trying to implement something similar in C++,
but I get the following error:
Error 1 error C2664: 'int RefDef::AddDrawSurf(surfaceType_t *)' : cannot convert argument 1 from 'void *' to 'surfaceType_t *'
It would appear I cannot perform this type of cast in C++, or maybe there is
something else I am unable to understand. I am not very familiar with C++ and
would love to figure out how to set up something similar using it.
I am assuming this has something to do with type checking in C++, so it is not
allowed. How can I implement something similar in C++ in a safe way?
This works in C because structs are simply blocks of memory with each element in the struct laid out consecutively. This cast works because the first n bytes of a srfPoly_t struct consist of the surfaceType_t enum within that struct. The called function tries to interpret the passed-in srfPoly_t as a surfaceType_t, and succeeds because the first n bytes of the argument are, in fact, a surfaceType_t. Do not do this without a very good reason.
Casts from void*'s do not automatically occur in C++ as they do in C. You can use reinterpret_cast to explicitly cast between two different types of structs:
srfPoly_t* mySrfPoly_t;
surfaceType_t* mySurfaceType = reinterpret_cast<surfaceType_t*>(mySrfPoly_t);
I got the following error
error C2440: 'initializing' : cannot convert from 'const int' to 'int
[16]'
My code is like this
static int Count[MAX_STATION_NO] = 0;
I got error on above line. Can someone tell me what is the problem in the above line?
You're treating an array as a pointer, which is illegal. You can't assign an array to a value.
Perhaps you want this:
static int Count[MAX_STATION_NO] = {0};
You are creating an array and setting the arrays value to '0'. What I think you wish to do is:
static int Count[MAX_STATION_NO] = {0}
This line is declaring an array of size 16, then you are assigning a single number to it, which is not syntactically correct. You need to use an array initializer:
{ 16, 2, 77, 40, 12071 ... }
Curly brace {} are required to initialize arrays.
eg:
static int Count[MAX_STATION_NO]={1,2,3};
Maybe this link could help you: http://www.cplusplus.com/doc/tutorial/arrays/
Your initializer needs to be in braces:
static int Count[MAX_STATION_NO] = { 0 };
Btw: static arrays have their content initialized with 0 anyway so you the above is equivalent to:
static int Count[MAX_STATION_NO];