I'm currently trying to make an enemy in a game. The Enemy is meant to move towards the player using the player position (x and y coordinate) and comparing it to the enemy's coordinates. however I seem to be having problems with the identifiers.
void DinoEnemy::Update()
{
DinoEnemy GetPosition(int& dinox, int& dinoy); ///calling a function that should return dinox and diny
m_AnimatedSprite.SetCurrentAnimation(E_DinoState_Hatching);
GameStateManager* pGameStateManager = C_SysContext::Get<GameStateManager>();
GameState* pCurrentGameState = pGameStateManager->GetCurrentGameState();
GameObject* PlayerPos = pCurrentGameState->GetPlayer();
if (PlayerPos)
{
int playerposX = 0;
int playerposY = 0;
PlayerPos->GetPosition(playerposX, playerposY);
}
if (dinox << playerposX) ///Here is where the error is.
{
dinox++;
}
}
dinox and playerposX are undeclared in the final if statement
Thanks in advance ;u;
That's not how you call a function
You have
DinoEnemy GetPosition(int& dinox, int& dinoy);
But that's no function call as your comment suggests, but a function declaration. You meant to declare two variables, then call the function (as you did later on in your code, so why do it wrong here?):
int dinox;
int dinoy;
GetPosition(dinox, dinoy);
Beware: If GetPosition reads from dinox and dinoy you must intialize the values, but it seems like it only writes them.
The scope of playerposX is wrong
The variables playerposX and playerposY are only visible inside the if-block, simply declare them outside of it:
int playerposX = 0;
int playerposY = 0;
if (PlayerPos)
{
PlayerPos->GetPosition(playerposX, playerposY);
}
There should probably be an else that handles the case when PlayerPos == nullptr. After all it doesn't make sense to compare the players position to something if the player doesn't have any position.
Little typo
if (dinox << playerposX)
Here you probably don't want a bitshift (<<) but rather a smaller-than-comparison (<).
There will be an issue with the scope of playerposX. Since it is declared inside the if block, it gets out of scope outside of the if block.
Additionally, in case PlayerPos cannot be translated to true, e.g., if it is NULL, playerposX will never be declared at all.
You may want to declare playerposX outside of the if block. Or add the second if block within the scope of the first.
In other words
if (PlayerPos)
{
int playerposX = 0;
int playerposY = 0;
PlayerPos->GetPosition(playerposX, playerposY);
if (dinox << playerposX)
{
dinox++;
}
}
Related
I am writing a toy compiler, which compile a c/c++ like language to c++.
I am using bison, but in this structure is hard to handle when variable became out of scope.
In the source lanugage in the whole main function there can be only one variable with the same name, it is good, but there is a problem what I cannot solve.
I cannot make c++ code like this, because c++ compiler throw semantical error:
'var' was not declared in this scope.
int main()
{
if (true)
{
int var = 4;
}
if (true)
{
var = 5;
}
}
The source language has while, if and if/else statements.
I have to throw semantical error if a declared variable is assinged in out of scope.
For example:
This should be semantical error, so I cannot generetad this code:
int main()
{
while(0)
{
int var = 1;
}
if (1)
{
var = 2;
}
}
This also have to be semantical error:
int main()
{
if (0)
{
int var = 1;
}
else
{
if (1)
{
var = 5;
}
}
}
And this is allowed, I can generate this code:
int main()
{
if (0)
{
}
else
{
int var = 1;
if (1)
{
while (0)
{
while (0)
{
var = 2;
}
}
}
}
}
I tried lot of things, but I cannot solve when there is nested if, if/else or while.
I read tons of tutorials about symbol table, but none of them can explain properly how to manage a variable if it is become out of scope.
If you familiar with this topic and with bison, please do not just give me hints, like "use stack, and mark a variable if it become out of scope". I found lot of article about it.
Instead of please give me pseudocode or concrate implementation sketch.
I think it cannot be so much difficult, because in the whole main function there can be one variable with the same name as I wrote.
Symbol table:
struct SymbolType
{
int lineNumber;
std::string identifier;
int identifierValue;
Type type;
int functionArgumentNumber;
Type functionReturnType;
Type markType;
bool outOfScope;
};
class Symbol
{
public:
void AddVariable(int _lineNumber, std::string _identifier, int _identifierValue, Type _type, int _functionArgumentNumber, Type _functionReturnType, Type _markType, bool _outOfScope);
void AddMarker(int _lineNumber, std::string _scopeName, Type _markType);
bool FindVariable(std::string _identifier);
int FindVariableValue(std::string _identifier);
void Remove();
void Print();
std::vector<SymbolType> symbolTable;
private:
int lineNumber;
std::string identifier;
int identifierValue;
Type type;
int functionArgumentNumber;
Type functionReturnType;
Type markType;
bool outOfScope;
};
Now let's assume the following: While you are in a nested scope you cannot add a variable to a parent scope. So we can work e.g. with a stack like structure (push/pop at the end only suffices, but with read access to all entries – the latter requirement disqualifying std::stack, so we'd operate e.g. on std::vector instead).
Encountering the declaration of a new variable:Run up the entire stack to see if that variable exists already. If so, issue an error ('duplicate declaration/definition').
Encountering accessing a variable: Run up the entire stack to see if that variable exists; if not, issue an error ('not declared/defined' – I wouldn't differentiate between the variable not having been defined ever or having left the scope).
On leaving a scope, run up the stack and remove any variable that resides in that scope.
To be able to do 3. you have (at least) two options:
With every stack entry provide an identifier for the respective scope, could be simple counter. Then delete all those variables that have the same counter value. If you fear the counter might overflow, then reduce it by 1 as well (then it would always represent current scope depths).
Have a sentinel type – that one would be pushed to the stack on opening a new scope, compare unequal to any variable name, and on leaving a scope you'd delete all variables until you encounter the sentinel – and the sentinel itself.
This processing makes your outOfScope member obsolete.
Your addVariable function takes too many parameters, by the way – why should a variable need a return type, for instance???
I recommend adding multiple functions for every specific semantic type your language might provide (addVariable, addFunction, ...). Each function accepts what actually is necessary to be configurable and sets the rest to appropriate defaults (e.g. Type to Function within addFunction).
Edit – processing the example from your comment:
while(condition)
{ // opens a new scope:
// either place a sentinel or increment the counter (scope depth)
int var = 1; // push an entry onto the stack
// (with current counter value, if not using sentinels)
if (true)
{ // again a new scope, see above
var = 2; // finds 'var' on the stack, so fine
} // closes a scope:
// either you find immediately the sentinel, pop it from the stack
// and are done
//
// or you discover 'var' having a counter value less than current
// counter so you are done as well
} // closing next scope:
// either you find 'var', pop it from the stack, then the sentinel,
// pop it as well and are done
//
// or you discover 'var' having same counter value as current one,
// so pop it, then next variable has lower counter value again or the
// stack is empty, thus you decrement the counter and are done again
As the title suggest how can i declare a variable inside loop and use it outside?
EXAMPLE
void Function(String s)
{
for(i = 0; s[i] != '\0'; ++i)
{
switch(s[i])
{
case 'i':int x;
case 'd':double x;
case 'c':char x;
}//end of switch
}//end of for loop
//now i want to use 'x' here,i.e.,out side the loop how will i do it?
}//end of void function
EDIT I know the scope thing but i saw some one achieving this with template class/function but I dont know how to use template class/func to do this..so anyone knows?
{ } - are scope delimiters, anything you define inside it, cannot be access outside. So if you want, you can declare it outside loop and then you can access it outside as well as inside loop.
No. Simplified, that's what a scope is - the scope within which declared variables are accessible.
You need to declare the variable in the outer scope if you want to access it from there:
{
int x = 0;
for (...)
{
x= 1;
}
if (x ==1)
{
printf("it works");
}
}
I have a pretty standard class with some public member functions and private variables.
My problem originally stems from not being able to dynamically name object instances of my class so I created an array of pointers of the class type:
static CShape* shapeDB[dbSize];
I have some prompts to get info for the fields to be passed to the constructor (this seems to work):
shapeDB[CShape::openSlot] = new CShape(iParam1,sParam1,sParam2);
openSlot increments properly so if I were to create another CShape object, it would have the next pointer pointing to it. This next bit of code doesn't work and crashes consistently:
cout << shapeDB[2]->getName() << " has a surface area of: " << shapeDB[2]->getSA() << shapeDB[2]->getUnits() << endl;
The array of pointers is declared globally outside of main and the get() functions are public within the class returning strings or integers. I'm not sure what I'm doing wrong but something relating to the pointer set up I'm sure. I'm writing this code to try and learn more about classes/pointers and have gotten seriously stumped as I can't find anyone else trying to do this.
I'm also curious as to what the CShape new instances get named..? if there is any other way to dynamically create object instances and track the names so as to be able to access them for member functions, I'm all ears.
I've tried all sorts of permutations of pointer referencing/de-referencing but most are unable to compile. I can post larger chunks or all of the code if anyone thinks that will help.
class CShape {
int dim[maxFaces];
int faces;
string units;
string type;
string name;
bool initialized;
int slot;
public:
static int openSlot;
CShape();
CShape(int, string, string); // faces, units, name
~CShape();
void initialize(void);
// external assist functions
int getA(void) {
return 0;
}
int getSA(void) {
int tempSA = 0;
// initialize if not
if(initialized == false) {
initialize();
}
// if initialized, calculate SA
if(initialized == true) {
for(int i = 0; i < faces; i++)
{
tempSA += dim[i];
}
return(tempSA);
}
return 0;
}
string getUnits(void) {
return(units);
}
string getName(void) {
return(name);
}
// friend functions
friend int printDetails(string);
};
// constructor with values
CShape::CShape(int f, string u, string n) {
initialized = false;
faces = f;
units = u;
name = n;
slot = openSlot;
openSlot++;
}
My guess is you use the CShape constructor to increment CShape::openSlot?
You're probably changing the value before it's read, thus the pointer is stored in a different location.
Try replacing openSlot with a fixed value to rule out this CShape::option.
-- code was added --
I'm pretty sure this is the problem, the constructor is executed before the asignment, which means the lhs. will be evaluated after CShape::openSlot is incremented.
Once I assumed that these two have the same meaning but after reading more about it i'm still not clear about the difference. Doesn't the local scope sometimes refer to scope of function?
and what does it mean that only labels have a function scope?
void doSomething()
{ <-------
{ <---- |
| |
int a; Local Scope Function Scope
| |
} <---- |
} <-------
Function Scope is between outer { }.
Local scope is between inner { }
Note that, any scope created by {``} can be called as the local scope while the {``} at the beginning of the function body create the Function scope.
So, Sometimes a Local Scope can be same as Function Scope.
what does it mean that only labels have a function scope?
Labels are nothing but identifiers followed by a colon. Labeled statements are used as targets for goto statements. Labels can be used anywhere in the function in which they appear, but cannot be referenced outside the function body. Hence they are said to have Function Scope.
Code Example:
int doSomething(int x, int y, int z)
{
label: x += (y + z); /* label has function scope*/
if (x > 1)
goto label;
}
int doSomethingMore(int a, int b, int c)
{
if (a > 1)
goto label; /* illegal jump to undefined label */
}
Local scope is the area between an { and it's closing }. Function scope is the area between the opening { of a function and its closing }, which may contain more "local" scopes. A label is visible in the entirety of the function within which it is defined, e.g.
int f( int a )
{
int b = 8;
if ( a > 14 )
{
int c = 50;
label:
return c - a - b;
}
if ( a > 7 ) goto label;
return -99;
}
int c is not visible outside its enclosing block. label is visible outside its enclosing block, but only to function scope.
Doesn't the local scope sometimes refer to scope of function?
Yes. In most C-derived languages, variables are valid in the scope in which they're declared. If you declare a variable inside a function, but not within any other code block, then that variable is usually called a "local" or "automatic" variable. You can refer to it anywhere in the function. On the other hand, if you declare your variable inside another code block -- say, in the body of a conditional statement, then the variable is valid only inside that block. Several other answers here give good examples.
and what does it mean that only labels have a function scope?
Context would be helpful, but it means that you can't jump from one function to a label in a different function.
void foo(int a) {
if (a == 0) goto here; // okay -- 'here' is inside this function
printf("a is not zero\n");
goto there; // not okay -- 'there' is not inside this function
here:
return;
}
void bar(int b) {
if (b == 0) goto there; // okay -- 'there' is in this function
printf("b is not zero\n");
there:
return;
}
Not to stir up a hornet's nest, but the scope of labels probably won't come up too often. Labels are mainly useful with the goto statement, which is needed only very rarely if ever, and even if you did choose to use goto you probably wouldn't even think of trying to jump into a different function.
The scope of the function is slightly larger than the scope of the function body: The function arguments are in the outer scope, while local variables are only in the inner one. This is most visibly manifest in a function-try-block:
void f(int a) try {
// function body
} catch(...) {
// catch block
}
Inside the catch block, only the variables in function scope are still in scope, but not the local variables.
Of course you can and do also introduce further, deeper nested scopes all the time, e.g. in for loop bodies or conditional bodies.
bool m[3][3];
void f1()
{
int i;
// redefining a variable with the same name in the same scope isn't possible
//int i; //error C2086: 'int i' : redefinition
}
void f2()
{
int i; // ok, same name as the i in f1(), different function scope.
{
int i; // ok, same name as the i above, but different local scope.
}
// the scope if the following i is local to the for loop, so it's ok, too.
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (m[i][j])
goto loopExit;
}
}
loopExit:
std::cout << "done checking m";
// redefining a label with the same name in the same function isn't possible
// loopExit:; // error C2045: 'loopExit' : label redefined
}
void f3()
{
loopExit:; // ok, same label name as in f2(), but different function scope
}
So I'm trying my hand at some C++ after finishing up an introductory book, and I've become stuck. I've made a vector of objects that each have an SFML circle object as a member, and I want main() to go and draw these circles. The vector is called theBoard, but when I try to access it, I get the following error messages:
error: request for member 'theBoard' in 'GameBoard', which is of non-class type 'Board*'
error: 'theBoard' was not declared in this scope
I'm new to this (came from two years of Python), so I'm sure I made a mistake somewhere. Here is the relevant code for the board creation:
class Board
{
public:
//These are the member functions.
Board();
~Board();
vector<Space*> CreateBoard();
//This will be the game board.
vector<Space*> theBoard;
//These clusters represent the waiting areas for pieces not yet in the game.
vector<Space*> Cluster1;
vector<Space*> Cluster2;
vector<Space*> Cluster3;
private:
//These integers represent the number of spaces on each row, starting at the top (which is row [0])
vector<int> RowNums;
};
Board::Board()
{
//Fill in RowNums with the right values.
RowNums.push_back(1);
RowNums.push_back(17);
RowNums.push_back(2);
RowNums.push_back(17);
RowNums.push_back(1);
RowNums.push_back(1);
RowNums.push_back(5);
RowNums.push_back(2);
RowNums.push_back(7);
RowNums.push_back(2);
RowNums.push_back(11);
RowNums.push_back(3);
RowNums.push_back(17);
RowNums.push_back(4);
RowNums.push_back(17);
//Then, create the board.
theBoard = CreateBoard();
}
CreateBoard() is a very, very long function that returns a vector of pointers to Space objects. I doubt there's a problem here, as the only error message I get crops up when I try to access the circle members of Space objects in main(). It seems to me as though I have declared theBoard in the relevant scope, that is, as a data member of the Board class.
My main() function, in case it's important:
int main()
{
//This sets up the display window.
sf::RenderWindow App(sf::VideoMode(1200, 900, 32), "Malefiz");
//This creates the board on the heap, and a pointer to it.
Board* GameBoard = new Board();
cout << "Board made.";
//This is the game loop.
while(App.IsOpened())
{
//This is used to poll events.
sf::Event Event;
while(App.GetEvent(Event))
{
//This closes the window.
if(Event.Type == sf::Event::Closed)
{
App.Close();
}
}
//This gets the time since the last frame.
//float ElapsedTime = App.GetFrameTime();
//This fills the window with black.
App.Clear(sf::Color(200, 200, 125));
//This draws the places into the window.
for(int i = 0; i < GameBoard.theBoard.size(); ++i)
{
App.Draw(GameBoard.*theBoard[i].m_Circle);
}
//This displays the window.
App.Display();
}
return EXIT_SUCCESS;
}
In your main() function, GameBoard is a Board *, not a Board. So to access members, you need to use -> instead of .. e.g.:
GameBoard->theBoard.size()
[Some people (I am one of them) like to name their pointer variables with a leading p or ptr prefix, in order to make this kind of irritation explicitly clear.]
GameBoard is a pointer to a Board object, and thus you need to use the "->" operator instead of the "." operator to access any of its member variables or methods.
The error is quite explicit if you read it carefully:
error: request for member 'theBoard' in 'GameBoard', which is of non-class type 'Board*'
error: 'theBoard' was not declared in this scope
The first line is telling you that you have a pointer to a Board object and you are trying to access a member directly. That is:
Board *p = ...
p.theBoard; // Error, should be p->theBoard, as p is a pointer
Also note that GameBoard.*theBoard[i].m_Circle might not be what you want, you probably want (I am guessing as there are important bits missing) something like GameBoard->theBoard[i]->m_Circle.
GameBoard is a pointer, so the syntax should be this:
for(int i = 0; i < GameBoard->theBoard.size(); ++i)
{
App.Draw((GameBoard->theBoard[i])->m_Circle);
}
Since elements of theBoard also are pointer, so I used the pointer notation when accessing m_Circle.