I have the following piece of code -
string classNeeded;//set to either "Max" or "Min"
if(strcmp(classNeeded, "Max") == 0)
{
Maximum maxi;//object of class Maximum declared
}
else
{
Minimum mini;//object of class Minimum declared
}
while(/*Conditions*/)
{
//Some processing
//Use maxi or mini depending on which one is declared
}
I need to check if maxi is declared and use it or if it is not declared, use mini. How do I check if an object is declared or not in C++ Visual Studio 2005?
P.S.: I'm new to coding in VS2005 C++
You can't check if an object in the local scope is created at runtime. You can't even make a decision on that. It either is or it isn't, and is determinable by simply reading the code. What you're doing now is creating 2 objects in two seperate scopes. They don't exist outside the scope in which they are created, so you can't use them later, down in your while loop. You could use pointers with dynamic allocation, but a better idea is to factor out your while loop into a pair of overloaded functions.
void DoIt(Maximum maxi)
{
while(/*Conditions*/)
{
//Some processing
//Use maxi
}
}
void DoIt(Minimum mini)
{
while(/*Conditions*/)
{
//Some processing
//Use mini
}
}
Then:
if(strcmp(classNeeded, "Max") == 0) // no comment
{
DoIt(Maximum());
}
else
{
DoIt(Minimum());
}
If the code in the while loop looks identical for both functions, just with a different object, you could use a template instead.
template<typename T>
void DoIt(T& object)
{
...
}
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
struct TodoItem
{
std::string todo;
};
const int MAX_STACK_SIZE = 5;
class TodoStackArray
{
public:
TodoStackArray(); //confusion here<---
bool isEmpty();
bool isFull();
void push(std::string todoItem);
void pop();
TodoItem* peek();
/* for grading purposes we need these following methods */
int getStackTop() { return stackTop; }
TodoItem** getStack() { return stack; }
private:
int stackTop;
TodoItem* stack[MAX_STACK_SIZE];
};
Above, is some declarations and a class from a header file for a current assignment. Our duty was to implement a stack program using this header file. However, I am a little confused as to the purpose of the TodoStackArray() in the Header File. Is this supposed to be a base constructor? Am I supposed to use it for anything??
I understand that this is somewhat situation specific but given that stack Arrays are STL I figured you might all be able to provide some insight. Thanks!
In case you want to see what I did with this header file...
TodoStackArray::TodoStackArray() //This, unsurprisingly, produces an error.
{
stackTop = -1;
stack[stackTop];
}
bool TodoStackArray::isEmpty()
{
return (stackTop == -1);
}
TodoItem* TodoStackArray::peek()
{
if(stackTop ==-1)
{
cout<< "Stack empty, cannot peak."<<endl;
}
else
{
return(stack[stackTop]);
}
}
bool TodoStackArray::isFull()
{
return(stackTop == 4);
}
void TodoStackArray::push(std::string todoItem)
{
if(stackTop >= 5)
{
cout<<"Stack full, cannot add new todo item."<<endl;
}
else
{
stack[stackTop++];
stack[stackTop]->todo = todoItem;
}
}
void TodoStackArray::pop()
{
if(stackTop == -1)
{
cout<<"Stack empty, cannot pop an item."<<endl;
}
else
{
stackTop--;
}
}
Also, to be clear, we were not provided driver software. They will be assessing from their own stuff so we have to write our own driver software to test our functions. Hence the lack of any Main implementation.
Yes, TodoStackArray::TodoStackArray() really is your class' default constructor.
What you are supposed to do with it just as with any default constructor:
How are the class members supposed to be initialized if I create a new TodoStackArray?
The answer depends on what your class is supposed to look like in its initial state.
In you situation, "by default" a stack is empty. Setting the stackTop to -1 was not a bad idea and the rest of your implementation is consistent with that (stackTop == -1 clearly means "empty stack").
The odd thing that happens in your constructor is this:
stack[stackTop];
What is, according to you, the purpose of this line? You are reading the value in your array at a negative index, and we all know this kind of things never end well.
Constructors are made to initialize your data. Here you are reading something you didn't initialize at an index that doesn't exist. Doesn't make much sense, does it? :)
Just get rid of this line and you should be able to move on. Here is an equivalent implementation using member initializer list (which are considered nicer):
TodoStackArray::TodoStackArray() : stackTop(-1)
{
// notice: no body required here
}
Have fun!
It acts like this.
fun();//return 1;
for (int i=0;i++;i<100)
fun();//return 2;
fun();//return 3;
I don't want to do it manually, like:
static int i=0;
fun(){return i};
main()
{
i++;
fun();//return 1;
i++;
for (int i=0;i++;i<100)
fun();//return 2;
i++;
fun();//return 3;
}
New classes and static variables are allowed.
I am trying to design a cache replacement algorithm. Most of the time I use the LRU algorithm, but, if I use LRU algorithm inside a loop I would very likely get a cache thrashing.
https://en.wikipedia.org/wiki/Thrashing_(computer_science)
I need to know if I am inside a loop. Then I can use the LFU algorithm to avoid thrashing.
An obvious way of doing this would be using the __LINE__ macro. It will return the source code line number, which will be different throughout your function.
It is not possible within c++ for a function to know whether or not it is inside a loop 100% of the time. However, if you are happy to do some manual coding to tell the function that it is inside a loop then making use of C++'s default parameters you could simply implement a solution. For more information on default parameters see http://www.learncpp.com/cpp-tutorial/77-default-parameters/. Also, because Global variables are generally frowned upon I have placed them in a separate namespace in order to prevent clashes.
namespace global_variables {
int i = 0;
}
int func(bool is_in_loop = false) {
if (is_in_loop)
{
//do_something;
return global_variables::i;
}
else
{
//do_something_else;
return global_variables::i++;
}
}
int main()
{
// Calling function outside of loop
std::cout << func();
// Calling function inside of loop
for (int j=0;j<100;j++)
{
// is_in_loop will be overided to be true.
std::cout << function(true);
}
return 0;
}
Well, I have an abstract virtual machine ("PAWN") which is running from my code and the scripts can execute functions, those functions are registered to the script from the C code which gets executed by my C++ code.
The c++ code has to supply an array in the form of
{ "name_i_want_the_function_to_have_in_the_script" , function_in_my_cpp_code }
if the function is not in the array, it cannot be executed. (because it doesn''t "exist")
So this brings us to this:
My functions look like this:
//Pawn Functions
#define PWNFUNC(a) static cell AMX_NATIVE_CALL a(AMX *amx, cell *params)
namespace PawnFunc
{
PWNFUNC(GGV)
{
return pGameInterface->FindGameVersion();
}
};//namespace PawnFunc
and the array with the scripting functions information is in another file, like this:
AMX_NATIVE_INFO custom_Natives[] =
{
{ "GetGameVersion", PawnFunc::GGV },
{ 0,0 }
};
and the question is now:
is it possible to make that array auto updated? (before/at compile time or code initialization time)
as for now I have to add each function manually. Which is sometimes annoying and more prone for errors.
I would like to change it so I could do:
//Pawn Functions
#define PWNFUNC(a,b) ...?...
namespace PawnFunc
{
PWNFUNC(GGV,GetGameVersion)//{ "GetGameVersion", PawnFunc::GGV }, is now added to "custom_Natives" array
{
return pGameInterface->FindGameVersion();
}
};//namespace PawnFunc
Is this possible at all? If yes, how could I achieve this?
maybe it is possible to loop the namespace?
Edit: here is some pseudo code: http://ideone.com/btG2lx
And also a note: I can do it at runtime, but then it has to be done at DLLMain (my program is a DLL).
This #define will do the job, if you use a std::vector as the storage for your script info.
(Note that the standard guarantees that you'll still get a C-style array from &custom_Natives[0])
std::vector<AMX_NATIVE_INFO> custom_Natives;
#define PWNFUNC(NAME, FUNC) \
struct IMPL_ ## FUNC { \
IMPL_ ## FUNC() { \
AMX_NATIVE_INFO entry = { NAME, PawnFunc::FUNC }; \
custom_Natives.push_back( entry ); \
} \
} INSTANCE_ ## FUNC; \
static cell AMX_NATIVE_CALL FUNC(AMX *amx, cell *params)
Now code like this will both define the function and add the script entry to custom_Natives.
PWNFUNC("GetGameVersion", GGV)
{
return pGameInterface->FindGameVersion();
}
What I could come up with (assuming C-style arrays and C-linkage functions):
AMX_NATIVE_INFO custom_natives[] =
{
{ "GetGameVersion", TheGGVFunc },
{ 0, 0 }
};
// here a function call named `GetGameVersion` was encountered,
// so let's look it up using a naive linear search
const char *toBeCalled = "GetGameVersion"; // obtain this somehow
void (*fptr)(void) = NULL;
for (int i = 0; i < sizeof(custom_natives) / sizeof(*custom_natives) - 1; i++) {
const char *name = custom_natives[i].name;
if (strcmp(toBeCalled, name) == 0) {
fptr = custom_natives[i].func;
break;
}
}
if (fptr != NULL) {
fptr();
}
You can approximate it; the idea is to use a global std::vector instead of a C array, and to use constructors of global objects to extend the vector. That way your array will be initialized by the time main() starts executing. So instead of a custom_Natives array you would have a
std::vector<MethodArrayElementType> custom_Natives;
vector (replace MethodArrayElementType with the name of the struct which holds the string -> function pointer mapping). You can treat this vector like a plain C array by using &custom_Natives[0].
Then, right next to every function you define, you add a little Registrar class to register the method:
PWNFUNC(GGV) {
// Your implementation goes here...
}
struct GGV_Registrar {
GGV_Registrar() {
MethodArrayElementType e = { "GetGameVersion", GGV };
custom_Natives.push_back( e );
};
} GGV_Registrar_instance;
The constructor of the global GGV_Registrar_instance constructor will be called before main() is called, and it will update the custom_Natives vector.
We do something like this, but instead of using an array we use a linked list. So your example would become
namespace PawnFunc
{
PWNFUNC(GGV)
{
return pGameInterface->FindGameVersion();
}
PawnRegister GGVfunc( "GetGameVersion", GGV );
};//namespace PawnFunc
The constructor for PawnRegister adds all the objects (like GVVfunc) to a linked list. When your script engine wants to lookup a function, it traverses the list instead of scanning the array. I suppose you could set up PawnRegister to add entries to an array instead.
Is it correct to put dynamic_cast in loop??
//Searches for the reservation with the given reservation number, and //deletes it. Uses the confirmReservation function if the reservation to be //deleted was an OK one
void cancelReservation(string resNum)
{
for (int i=0;i<seats+waitingListMax;i++)
{
for (int seat=i;seat<seats;seat++)
{
Ok* okptr=dynamic_cast <Ok*>(reservations[seat]);
}
for ( int wait=seats;wait<seats+waitingListMax;wait++)
{
Waiting* waitingptr=dynamic_cast <Waiting*>(reservations[wait]);
}
if ((reservations[i]!=0) && (reservations[i]->getReservationNumber()==resNum))
if (okptr)
{
//doing somting
}
if (waitptr)
{
//doing somthing else
}
}
Nothing wrong in putting it under a for loop.
Your class should be polymorphic though but that is a basic condition for using dynamic_cast.
In your example, You are not really acheiving much because you overwrite the pointer on every iteration. But that is probably your simplification of original code.
There's nothing wrong with using dynamic_cast within a loop.
But your code does have a different problem: the pointers okptr and waitingptr are only scoped to the innermost {}, so can't be used later.