I'm trying to make a simple program that takes a user command, executes a function, then returns to the original function so the user can enter another command, much like windows command prompt. Upon browsing the similar questions I read that returning to main is not good programming so I want to ask:
How can I make a function that has access to the other functions but the other functions can return to once they finish their process?
After a function returns, control is returned to the calling function.
Example:
#include <iostream>
int other_function(){
std::cout << "In other_function...\n";
return 0;
}
int main(){
std::cout << "Calling other_function()...\n";
int ret_value = other_function();
std::cout << "Back in main. other_function returned "
<< ret_value << ".\n";
return 0;
}
This little program starts in main, calls other_function and then returns back to main. It prints, out the messages with std::cout as well. Try the program if you don't understand the concept.
Also, I personally see no problem with doing all of this in main, perhaps in a while-loop. What people mean (generally) when they say you shouldn't always return control to main is that you want to keep all of your functions short, preferably about as large as your screen. However, the main function is there for a reason, so use it (with care).
Just make sure that the functions have been declared (or #included), and your function should be able to call them all.
Good luck!
There's absolutely NO problems in returning to main() function.
In your case, you can do an algorithm in a way like this:
Step 1: Start Main() function
Step 2: Read the command from the user
Step 3: Compare the command by using if() and strcmp() function.
Step 3.a: Call the function for the command.
Step 4: Repeat through step 2.
Related
Everytime, std::cout is used from the main function or other functions, I want to copy the contents of a logfile to a Fltk GUI Window.
I've implemented a function which does the copying part. I want to know if its possible to make this function run every time std::cout or maybe, std::endl is executed in the code.
How can I implement this?
EDIT:
For more clarification,
The function which needs to run every time is:
void printProgress(const std::string& strProgress)
{
std::ostringstream strResultTextStream;
strResultTextStream << m_pLogOutput->value();
strResultTextStream << strProgress;
m_pLogOutput->value(strResultTextStream.str().c_str());
}
Adding data to the output window (fl_multiline_output) requires the 4 lines of code above. Right now I have redirected the standard output messages to a log file. I wanted to run this function everytime to copy the contents of the logfile to m_pLogOutput(the Output window)
I think you could use #define to your advantage:
#define cout f(parameter),cout
where f() is your function. Change cout with std::cout if you want, I don't think that will provoke errors.
I am relearning C++. I was quite a noob before but I am going over the basics again and hopefully going further. My main question is, at the end of the main loop, is there a way to call the function again instead of ending the programme by returning 0. So something along the line of:
........
return main;
}
The standard C++ says...
5.2.2.9 Recursive calls are permitted, except to the function named main
"The Standard" at https://isocpp.org/std/the-standard
You could certainly do something like this:
int main()
{
while(1==1) /* (1==1) is always true. */
{
/* Do the hokey pokey, turn yourself around, and do whatever else you feel like doing. */
}
/* The program will never reach this point unless you explicitly break out of the loop. */
return 0;
}
This will result in a program that just repeats over and over again until you kill it. This is, of course, bad style, but it will work if you just need to get something up and running quickly.
As Trevor Hickey mentions, you could call break from within the loop and break out.
I am trying to do a recursive directory listing using a multi threaded approach. The following code works fine when replacing the async calls as a normal single threaded recursive function call but when implemented with async, the recursively started threads all seem to terminate when the initial async call made from main finishes as the output shows several calls to the function starting but the only directory where all of the files are output is the initial one and "Finished" is only output once although "Started" is output several times and some other directory's files are also output. I suspect I am missing something fundamental. Can anyone explain what is wrong with this code?
#include <filesystem>
#include <future>
#include <functional>
#include <concurrent_vector.h>
#include <concurrent_queue.h>
#include <iostream>
using namespace std;
using namespace std::tr2::sys;
using namespace concurrency;
concurrent_vector<future<void>> taskList;
void searchFiles(wstring path, concurrent_queue<wstring>& fileList)
{
wcout << L"Started " << path << endl;
wdirectory_iterator directoryIterator(path);
wdirectory_iterator endDirectory;
for( ; directoryIterator != endDirectory; ++directoryIterator)
{
wcout << path + L"/" + (wstring)directoryIterator->path() << endl;
if ( is_directory(directoryIterator->status() ) )
{
taskList.push_back( async( launch::async, searchFiles, path +
L"/" + (wstring)directoryIterator->path(), ref(fileList) ));
}
else
{
fileList.push( path + L"/" + (wstring)directoryIterator->path() );
}
}
wcout << L"Finished " << path << endl;
}
int main()
{
concurrent_queue<wstring> fileList;
wstring path = L"..";
taskList.push_back( async( launch::async, searchFiles, path, ref(fileList) ));
for (auto &x: taskList)
x.wait();
}
BTW some might ask why I am not using wrecursive_directory_iterator. Apparently wrecursive_directory_iterator will throw an exception and stop with no way to continue if you do not have read permission so this method should allow you to continue on in that case.
The problem is the range-based for loop.
If we take a look at how the range-based for statement is defined, we see that the end-iterator of the loop will only be calculated once. At the time of entering the loop, there is probably(this is a race) only one future in your vector(the one you pushed back in the line above). Thus after that task finishes, the iterator will be incremented and be equal to your old end-iterator and the loop will finish even though the vector might now contain more elements which got pushed back in your first task. There are even more problems to this.
The destructor of the vector which will be called after finishing the loop should normally call the destructor of all its elements which for a future from std::async would be equal to calling wait, though you are still adding elements to the vector while it's already in its destructor, which is probably UB.
Another point is that the end-iterator you created on entering the for-loop will be invalidated as soon as you push_back to your vector in your first thread, this means that you are operating on invalidated iterators.
As a solution I would propose to avoid the global task-list and instead use a local task-list in your searchFiles function, you can then wait on all your local futures in your searchFiles function on each level. This is a common pattern in non-managed recursive parallelism.
Note: I don't know all the details from the ppl concurrent_vector but I assume it behaves similar to a std::vector.
I am writing a program which executes tcl scripts. When the script has exit command, the program crashes with this error
DeleteInterpProc called with active evals
Aborted
I am calling Tcl_EvalFile(m_interpreter, script.c_str()) where script is the file name.
Also I have tried Tcl_Eval with arguments interpreter and "source filename". Result is the same. Other tcl comands (eg. puts) interpreter executes normally. How this can be fixed?
#include <tcl.h>
#include <iostream>
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
//Tcl_Preserve(interp);
Tcl_Eval (interp, "exit");
//Tcl_Release(interp);
std::cout << "11111111111" << std::endl;
return 0;
}
This is the simple case. "11111111111" are not printed. As I understand whole program is exited when calling Tcl_Eval (interp, "exit");. The result is same after adding Tcl_Preserve and Tcl_Release.
The problem is that the interpreter, the execution context for Tcl code, is getting its feet deleted out from under itself; this makes it very confused! At least you're getting a clean panic/abort rather than a disgusting hard-to-reproduce crash.
The easiest fix is probably to do:
Tcl_Preserve(m_interpreter);
// Your code that calls Tcl_EvalFile(m_interpreter, script.c_str())
// and deals with the results.
Tcl_Release(m_interpreter);
Be aware that after the Tcl_Release, the Tcl_Interp handle may refer to deleted memory.
(Yes, wrapping the Tcl_Preserve/Tcl_Release in RAII goodness is reasonable.)
If you want instead to permit your code to run after the script does an exit, you have to take additional steps. In particular, the standard Tcl exit command is not designed to cause a return to the calling context: it will cause the process to call the _exit(2) system call. To change it's behavior, replace it:
// A callback function that implements the replacement
static int
MyReplacementExit(ClientData unused, Tcl_Interp *interp, int argc, const char *argv[])
{
// We ought to check the argument count... but why bother?
Tcl_DeleteInterp(interp);
return TCL_OK;
}
int main() {
Tcl_Interp *interp = Tcl_CreateInterp();
// Install that function over the standard [exit]
Tcl_CreateCommand(interp, "exit", MyReplacementExit, NULL, NULL);
// Important; need to keep the *handle* live until we're finished
Tcl_Preserve(interp);
// Or run whatever code you want here...
Tcl_Eval(interp, "exit");
// Important piece of cleanup code
if (!Tcl_InterpDeleted(interp))
Tcl_DeleteInterp(interp);
Tcl_Release(interp);
// After this point, you *MUST NOT* use interp
std::cout << "11111111111" << std::endl;
return 0;
}
The rules for doing memory management in these sorts of scenarios are laid out in the manual page for Tcl_CreateInterp. (That's the 8.6 manual page, but the relevant rules have been true since at least Tcl 7.0, which is over 2 decades ago.) Once an interpreter is deleted, you can no longer count on executing any commands or accessing any variables in it; the Tcl library handles the state unwinding for you.
It might be better to replace (hide) the exit command and create your own exit command that exit your program gracefully. I'm not that good with C and the Tcl C Api, but I hope this can help you.
Eggdrop for example uses the die command to exit gracefully.
Having read a bit about function pointers and callbacks, I fail to understand the basic purpose of it. To me it just looks like instead of calling the function directly we use the pointer to that function to invoke it. Can anybody please explain me callbacks and function pointers? How come the callback takes place when we use function pointers, because it seems we just call a function through a pointer to it instead of calling directly?
Thanks
ps: There have been some questions asked here regarding callbacks and function pointers but they do not sufficiently explain my problem.
What is a Callbak function?
In simple terms, a Callback function is one that is not called explicitly by the programmer. Instead, there is some mechanism that continually waits for events to occur, and it will call selected functions in response to particular events.
This mechanism is typically used when a operation(function) can take long time for execution and the caller of the function does not want to wait till the operation is complete, but does wish to be intimated of the outcome of the operation. Typically, Callback functions help implement such an asynchronous mechanism, wherein the caller registers to get inimated about the result of the time consuming processing and continuous other operations while at a later point of time, the caller gets informed of the result.
An practical example:
Windows event processing:
virtually all windows programs set up an event loop, that makes the program respond to particular events (eg button presses, selecting a check box, window getting focus) by calling a function. The handy thing is that the programmer can specify what function gets called when (say) a particular button is pressed, even though it is not possible to specify when the button will be pressed. The function that is called is referred to as a callback.
An source Code Illustration:
//warning: Mind compiled code, intended to illustrate the mechanism
#include <map>
typedef void (*Callback)();
std::map<int, Callback> callback_map;
void RegisterCallback(int event, Callback function)
{
callback_map[event] = function;
}
bool finished = false;
int GetNextEvent()
{
static int i = 0;
++i;
if (i == 5) finished = false;
}
void EventProcessor()
{
int event;
while (!finished)
{
event = GetNextEvent();
std::map<int, Callback>::const_iterator it = callback_map.find(event);
if (it != callback_map.end()) // if a callback is registered for event
{
Callback function = *it;
if (function)
{
(*function)();
}
else
{
std::cout << "No callback found\n";
}
}
}
}
void Cat()
{
std::cout << "Cat\n";
}
void Dog()
{
std::cout << "Dog\n";
}
void Bird()
{
std::cout << "Bird\n";
}
int main()
{
RegisterCallBack(1, Cat);
RegisterCallback(2, Dog);
RegisterCallback(3, Cat);
RegisterCallback(4, Bird);
RegisterCallback(5, Cat);
EventProcessor();
return 0;
}
The above would output the following:
Cat
Dog
Cat
Bird
Cat
Hope this helps!
Note: This is from one of my previous answers, here
One very striking reason for why we need function pointers is that they allow us to call a function that the author of the calling code (that's us) does not know! A call-back is a classic example; the author of qsort() doesn't know or care about how you compare elements, she just writes the generic algorithm, and it's up to you to provide the comparison function.
But for another important, widely used scenario, think about dynamic loading of libraries - by this I mean loading at run time. When you write your program, you have no idea which functions exist in some run-time loaded library. You might read a text string from the user input and then open a user-specified library and execute a user-specified function! The only way you could refer to such function is via a pointer.
Here's a simple example; I hope it convinces you that you could not do away with the pointers!
typedef int (*myfp)(); // function pointer type
const char * libname = get_library_name_from_user();
const char * funname = get_function_name_from_user();
void * libhandle = dlopen(libname, RTLD_NOW); // load the library
myfp fun = (myfp) dlsym(libhandle, funname); // get our mystery function...
const int result = myfp(); // ... and call the function
// -- we have no idea which one!
printf("Your function \"%s:%s\" returns %i.\n", libname, funname, result);
It's for decoupling. Look at sqlite3_exec() - it accepts a callback pointer that is invoked for each row retrieved. SQLite doesn't care of what your callback does, it only needs to know how to call it.
Now you don't need to recompile SQLite each time your callback changes. You may have SQLite compiled once and then just recompile your code and either relink statically or just restart and relink dynamically.
It also avoids name collision. If you have 2 libs, both do sorting and both expect you to define a function called sort_criteria that they can call, how would you sort 2 different objects types with the same function?
It would quickly get complicated following all the if's and switches in the sort_criteria function, with callbacks you can specify your own function (with their nice to interpret name) to those sort functions.