Is it possible to get the command line arguments without receiving them via int main(int, char**)? I don't want to pass the arguments to multiple methods, so a global function would be perfect. Also, I do not want to store the arguments by myself via global variables. I'm running Windows and Linux.
edit:
Example:
int main()
{
int argc = GetArgumentCount();
char ** argv = GetArguments();
return 0;
}
edit:
It's possible to use LPTSTR WINAPI GetCommandLine(void); in win32.
https://msdn.microsoft.com/en-us/library/ms683156(v=vs.85).aspx
I'm looking for equivalent functions in Linux.
Is it possible to get the command line arguments without receiving
them via int main(int, char**)?
Yes, with platform-specific functions. But that's not necessary (see below).
I don't want to pass the arguments to multiple methods,
That's understandable. It's an anti-pattern also known as "tramp data".
Also, I do not want to store the arguments by myself via global variables.
Yes, global variables are rarely a good idea.
Here's an alternative approach: store them as a static local container object in some globally available non-member function which returns the container by reference.
Example:
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string>& Arguments()
{
static std::vector<std::string> arguments;
return arguments;
}
void f()
{
// use arguments anywhere else:
std::cout << Arguments()[0];
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments().push_back(argv[i]);
}
f();
}
Of course, this can be made more sophisticated. For example, you might want to prevent anyone else but main from changing the vector by wrapping the vector in a class and declaring main as a friend, something like this:
#include <iostream>
#include <string>
#include <vector>
class Arguments final
{
public:
static int Count()
{
return arguments.size();
}
static std::string Get(int index)
{
return arguments[index];
};
private:
Arguments() = delete;
friend int main(int argc, char* argv[]);
static std::vector<std::string> arguments;
};
std::vector<std::string> Arguments::arguments;
void f()
{
// use Arguments anywhere else:
std::cout << Arguments::Get(0);
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments::arguments.push_back(argv[i]);
}
f();
}
Note that special care is needed to avoid bugs at program shutdown, when static objects are destroyed. You must make sure that no destructor of a static object accesses Arguments, or else you risk undefined behaviour.
Is it possible to get the command line arguments without receiving them via int main(int, char**) ?
No (at least, not in portable manner), however you could put the usual argc, argv into some global variable (or other global data, often after parsing). And that could also be into some static data with other functions in the same translation unit retrieving it. Hence a reasonable (readable and portable) approach would be:
static int myargc;
static char **myargv;
int GetArgumentCount(void) {
return myargc;
}
char**GetArguments(void) {
return myargv;
}
int main(int argc, char**argv) {
myargc= argc;
myargv= argv;
/// etc....
Notice that on some systems or some implementations you might access to the command line arguments in some other ways.
dirty Linux specific tricks
For example, on Linux, using proc(5), you might parse /proc/self/cmdline but it is unreasonable to do that (on your Linux system, try to run od -cx /proc/self/cmdline in your terminal to guess what I mean), so I still recommend using int main(int argc, char**argv) and storing, in some global or static data, the argc and argv, or more probably, do some parsing of program arguments.
So on Linux, you might code your GetArgumentCount and GetArguments functions (by parsing /proc/self/cmdline, see also this) but it would be foolish to do so without using argc and argv from main (even if it is technically doable). Coding such a crazy GetArgumentCount and GetArguments which parses /proc/self/cmdline is left as an exercise to the masochistic reader.
Perhaps you need that because some static data's constructor -running before main and called before it from crt0- uses them; but in that case, your program's design is IMHO very wrong. I have no idea if similar dirty tricks are doable in Windows.
If you really think that is a good idea, you can easily make cor command line arguments global:
int argc_ = 0;
char** argv_ = NULL;
int main(int argc, char* argv[]) {
argc_ = argc;
argv_ = argv;
// ...
}
Related
Just faced with a situation and don't know what to do... Here is the code I have right now:
class IMyDbAccessor {
public:
int getSum(); // quite important for my case that it is not const.
// it does some caching. Of course I may use mutable,
// but actually it is not that important here.
};
void SomeBusinessLogic(IMyDbAccessor& dbacc) { /* implementation */ }
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(acc);
}
I don't like it, because it is not expressive enough. I would like to have
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { /* implementation */ }
to show that SomeBusinessLogic wants to own a passed object, so main should look like
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(std::move(acc));
}
But of course it is impossible... Does anyone know what was a reasoning for that? For me it makes a perfect sense.
Or my feelings are wrong and I should not make SomeBusinessLogic responsible for IMyDbAccessor ownership, so it's better to pass it as a const IMyDbAccessor&?
I don't like it, because it is not expressive enough.
Looks plenty expressive to me. Passing an object by reference means the function can operate on an existing object provided by the caller, not on a copy. No worries about managing ownership.
I would like to have
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { /* implementation */ }
to show that SomeBusinessLogic wants to own a passed object
That is not what an rvalue reference represents. An rvalue reference means that dbacc will refer to either a temporary object created by the compiler at the actual call site, or a pre-existing object that the caller passes with std::move(). Either way, the object that dbacc refers to is expected not to be used anymore after SomeBusinessLogic() exits, so SomeBuinessLogic() is allowed to "steal" ownership of any internal data held by the object that dbacc refers to, instead of make copies of it. This has nothing to do with ownership of the object itself. That still lies strictly with the caller.
so main should look like
int main(int argc, char** argv) {
MyDbAccessor acc(argv);
SomeBusinessLogic(std::move(acc));
}
But of course it is impossible...
What you are looking for is std::unique_ptr:
void SomeBusinessLogic(std:::unique_ptr<IMyDbAccessor> dbacc) { /* implementation */ }
int main(int argc, char** argv) {
std::unique_ptr<IMyDbAccessor> acc(new MyDbAccessor(argv));
SomeBusinessLogic(std::move(acc));
}
Or:
int main(int argc, char** argv) {
SomeBusinessLogic(std::make_unique<MyDbAccessor>(argv));
}
Only one std::unique_ptr at a time should ever hold a given pointer, as std::unique_ptr frees the memory being pointed at when destructed. That is what makes it "unique". When you see a std::unique_ptr, you know who the owner is. And passing a std::unique_ptr object by value to a function means it exists only for the lifetime of the function.
So, this approach makes it very clear that dbacc itself, not the caller, holds exclusive ownership of the IMyDbAccessor object, and will free that object when SomeBusinessLogic() exits (unless SomeBusinessLogic() decides to std::move() dbacc to another std::unique_ptr that is outside of SomeBusinessLogic()).
Or my feelings are wrong and I should not make SomeBusinessLogic responsible for IMyDbAccessor ownership, so it's better to pass it as a const IMyDbAccessor&?
I would, yes. Unless there is some compelling reason that SomeBusinessLogic() must take ownership away from the caller.
I think the type you are looking for is probably void SomeBusinessLogic(std::unique_ptr<IMyDbAccessor>)?
Indicates ownership is being transferred, and accepts derived objects
Do SomeBusinessLogic(std::forward(acc)).
For example:
#include <iostream>
#include <utility>
class IMyDbAccessor {
public:
virtual int getSum() = 0;
};
class MyDbAccessor : public IMyDbAccessor {
public:
virtual int getSum() { return 0; }
};
void SomeBusinessLogic(IMyDbAccessor&& dbacc) { std::cout << dbacc.getSum() << std::endl; }
int main(int argc, char** argv) {
MyDbAccessor acc;
SomeBusinessLogic(std::forward<MyDbAccessor>(acc));
}
Try it here:
http://cpp.sh/7pbrm
If you are looking for a way to give feedback "Hey I will modify this variable!" at the call location, I strongly recommend const pointers.
Then you have:
void SomeBusinessLogic(IMyDbAccessor* const dbacc) { /* implementation */ }
and
int main(int argc, char** argv) {
MyDbAccessor acc;
SomeBusinessLogic(&acc);
}
I found the functor can be used to simulate defining a function within a function like this
using namespace std;
int main(int argc, char* argv[])
{
struct MYINC {
int operator()(int a) { return a+1; }
} myinc;
vector<int> vec;
for (int i = 0; i < 10; i++) vec.push_back(myinc(i));
return 0;
}
But If I passed it to an outside function, such as std::transform like the following example, I've got a compiling error saying error: no matching function for call to ‘transform(std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, main(int, char**)::MYINC&)’
using namespace std;
int main(int argc, char* argv[])
{
struct MYINC{
int operator()(int a) { return a+1; }
} myinc;
vector<int> vec;
for (int i = 0; i < 10; i++) vec.push_back(i);
transform(vec.begin(), vec.end(), vec.begin(), myinc);
return 0;
}
So I put the definition outside the main function and all is OK now.
using namespace std;
struct MYINC{
int operator()(int a) { return a+1; }
} myinc;
int main(int argc, char* argv[])
{
vector<int> vec;
for (int i = 0; i < 10; i++) vec.push_back(i);
transform(vec.begin(), vec.end(), vec.begin(), myinc);
return 0;
}
Both versions compile fine with g++ 4.8.2, which is a C++11 compiler.
A C++03 compiler would however balk at instantiating a template with a local type, since that was not supported in C++03.
One solution, if that is indeed the root cause of the problem, is then to use a more recent compiler version or other compiler.
Another solution is to leverage that even in C++03 you can define a "real" function locally, by making it a static member function of a local class (in C++11 you can also do that by using a lambda expression).
However, except for dealing with such a problem, the functor has a general performance advantage over the "real" function, namely that with an object of a class instead of just a function pointer, and with the relevant operator() as inline, the compiler can optimize much better, because it knows the function implementation.
For reasons that aren't entirely clear to me there is (was) a well-known and quite annoying limitation in C++ 03 on which types you can use to instantiate a template.
Locally defined classes could not be used as parameters with templates, just because.
This by the way made quite difficult to make any decent use of the <algorithm> library because you could not keep the context of your code local, being forced instead to place all functors, comparators and the like at namespace level, making up funny names for them and placing them far from the point of use.
I have implemented the following class using CUDA streams
class CudaStreams
{
private:
int nStreams_;
cudaStream_t* streams_;
cudaStream_t active_stream_;
public:
// default constructor
CudaStreams() { }
// streams initialization
void InitStreams(const int nStreams = 1) {
nStreams_ = nStreams;
// allocate and initialize an array of stream handles
streams_ = (cudaStream_t*) malloc(nStreams_*sizeof(cudaStream_t));
for(int i = 0; i < nStreams_; i++) CudaSafeCall(cudaStreamCreate(&(streams_[i])));
active_stream_ = streams_[0];}
// default destructor
~CudaStreams() {
for(int i = 0; i<nStreams_; i++) CudaSafeCall(cudaStreamDestroy(streams_[i])); }
};
If I now run this simple code
void main( int argc, char** argv)
{
streams.InitStreams(1);
streams.~CudaStreams();
cudaDeviceReset();
}
after the cudaDeviceReset() call, I receive the following message:
Unhandled exception 0x772f15de in test.exe: 0x00000000.
What should I do before invoking the destructor to avoid this issue when using cudaDeviceReset()?
EDIT
If I add free(streams_); in the destructor, namely
~CudaStreams() {
for(int i = 0; i<nStreams_; i++) CudaSafeCall(cudaStreamDestroy(streams_[i])); // *
free(streams_); }
I receive the following error message
cudaSafeCall() failed at C:\Users\Documents\Project\Library\CudaStreams.cuh:79 : unknown error
where line 79 is that denoted by * in the destructor.
Furthermore, If I use the same instructions of the constructor and the destructor directly inside the code, namely
void main( int argc, char** argv)
{
int nStreams_ = 3;
cudaStream_t* streams_ = (cudaStream_t*) malloc(nStreams_*sizeof(cudaStream_t));
for(int i = 0; i < nStreams_; i++) CudaSafeCall(cudaStreamCreate(&(streams_[i])));
for(int i = 0; i<nStreams_; i++) CudaSafeCall(cudaStreamDestroy(streams_[i]));
free(streams_);
cudaDeviceReset();
}
everything works well. Perheps is something connected to a bad use of the class?
There are two problems here, both related to the destructor of your class and scope.
Firstly, let's start with a version of your main() which will work correctly:
int main( int argc, char** argv)
{
{
CudaStreams streams;
streams.InitStreams(1);
}
cudaDeviceReset();
return 0;
}
This works correctly because the destructor for streams is called exactly once (when streams falls out of scope), and before cudaDeviceReset is called.
Your original main() (or a compilable version of it, but more about that later...) fails for two reasons. Let's look at it again:
int main( int argc, char** argv)
{
CudaStreams streams;
streams.InitStreams(1);
streams.~CudaStreams();
cudaDeviceReset();
return 0;
}
Here you explicitly call the destructor for streams (which you should almost never do), then cudaDeviceReset, then the destructor is called again at the return statement when streams falls out of scope. The automatic calling the destructor after the context is destroyed is the source of the segfault/exception. The cudaStreamDestroy calls are trying to work on streams without a valid CUDA context. So the solution is not to have any classes which make CUDA API calls fall out of scope (or call their destructors explicitly) when there is no context.
If we made a third version like this:
int main( int argc, char** argv)
{
{
CudaStreams streams;
streams.InitStreams(1);
streams.~CudaStreams();
}
cudaDeviceReset();
return 0;
}
You will get a CUDA runtime error. Because the destructor gets call twice. The first time (explicit) it will work. The second (implict, out of scope) will produce a runtime error: you have a valid context, but are now trying to destroy non-existent streams.
As a final comment/question: How hard would it have been to post and actual compilable version of the code you showed in your original question? It literally required 5 extra lines to make it into a proper repro case someone else could actual compile and run. I find it a bit unreasonable to expect others to make a effort to answer what are basically debugging questions if you are not willing to make a similar effort in providing useful code and information which makes everyone's life that much easier. Think about it. [end of rant]
GLUT is a great API and it's very easy to use but I am having some difficulty with how it handles scope. When defining callbacks there is no option to pass parameters so it seems to me as though the programmer is forced to rely on global variables, which I find difficult to accept. Right now I have all the GLUT code in it's own module, running on it's own thread, and define a static pointer which I assign at the entry point to the module, like so:
Main module
int main( int argc, char** argv ) {
int foo;
boost::thread graphicsThread(glutMain, argc, argv, &foo);
//...
graphicsThread.join();
return 0;
}
GLUT module
static int* FOO_REF;
int glutMain( int argc, char** argv, int* foo ) {
FOO_REF = foo;
glutInit(&argc, argv);
//etc...
Is there a better solution than this?
If you're using freeglut or a derivative and willing to confine yourself to freeglut derivatives only it has a non-standard extension to solve exactly the problem. You can associate a void* with every window. If you make that a struct that contains all the per-window data you want you can avoid the globals entirely.
Synopsis:
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
void * glutGetWindowData();
glutSetWindowData(void *data);
What I did was declare a global.h for all my globals. And initialize them in main. For my "basic/general" variables (ie camera, position, iterationNumber,...) they were all declared seperately. In main:
include "global.h"
Vector position_g = ...
Vector angles_g = ...
int time_g = 0;
int main () {
...
}
But for the variables that were "section specific" ie only in one game mode/level, I made a union and an enum.
enum mainGame{skipLevel, ...};
enum mainMenu {viewingSettings, ...};
typedef union generic_union {
int i;
char c;
bool b;
char s[100]; // or char * s;
float f;
} generic;
And declared a globalData variable.
extern generic * globalData; // in global.h
generic * globalData = NULL; // in main
Which can now be used:
int main () {
...
globalData = malloc (sizeof (generic)*numGlobals);
globalData[skipLevel].b = false;
...
}
Now when in your key press handling function, you can assign a key to toggle globalData[skipLevel]. And in any other file all you have to do is include global.h.
include "global.h"
void onKeyPress (... ) {
If (inMainGame) {
If (key == SPACE) {
globalData [skipLevel] = true;
}
}
And finally the use:
include "global.h"
void levelManager () {
...
if (globalData[skipLevel]) level++;
...
}
Pros
Only have to lug around 1 variable and one include.
You can free variables you no longer want or are using in that instance. (very useful for reducing "pollution"). If one game mode only needs 1 variable, thats all you have to store, if it needs 48, just as easy!
Can easily handle any variable type, by adding it to the union.
Totally Portable
Cons
Have to remember variable type to dereference the generic union (not that hard)
And watchout for enums being used (you can use a style for enums like mainMenu_e to solve this)
Adds complexity, but as the variable number grow, a system like this because well worth it.
Personally I find this very neat despite the few extra moving parts.
If this is unclear let me know, and Ill try to fix it :)
I have some code here to call minizip(), a boilerplate dirty renamed main() of the minizip program, but when I compile, I get *undefined reference to `minizip(int, char**)*. Here's the code.
int minizip(int argc, char* argv[]);
void zipFiles(void)
{
char arg0[] = "BBG";
char arg1[] = "-0";
char arg2[] = "out.zip";
char arg3[] = "server.cs";
char* argv[] = {&arg0[0], &arg1[0], &arg2[0], &arg3[0], 0};
int argc = (int)(sizeof(argv) / sizeof(argv[0])) - 1;
minizip(argc, argv);
}
int minizip(argc,argv)
int argc;
char *argv[];
{
...
}
Is all of that code in the same file? If not, and if the caller is C++ code and minizip is C code, the caller might need the minizip declaration within an extern "C" block to indicate that it will be calling a C function and therefore will need C linkage.
(Also, don't retype error messages. Copy and paste them so that they are exact. In this case, the compiler most likely reported an undefined reference to minizip(int, char**).)
Why are you declaring the function arguments again in:
int minizip(argc,argv)
int argc;
char *argv[];
{
...
}
It' should say
int minizip(int argc,char *argv[])
{
...
}