What does each of these `const`s mean? - c++

Normally people write the main function like this:
int main( int argc, char** argv )
However, this came to my mind:
int main( const int argc, const char* const* const argv )
or maybe I should write it like this cause it seems more intuitive:
int main( const int argc, const char *const *const argv )
What does each of the consts mean in argv (I think I understand them all but am still not sure)?
Also is this a valid code? What issues/limitations can it cause when using argv inside main?
Now what's the difference between this one and the latter:
int main( const int argc, const char* const argv[] )

The prototype is defined as "int main( int argc, char** argv )"
There is really no point in using a const pointer to access the parameters later unless you don't want to get it changed, which is up to you
The purpose of const pointers is to make sure that they are not changed throughout the code. You can live without them, but it helps avoid other issues, bugs for example.
On the other side, there is no performance gain (Optimizing_compiler)
1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;9) or in some other implementation-defined manner.
2 If they are declared, the parameters to the main function shall obey the following
constraints:
— The value of argc shall be nonnegative.
— argv[argc] shall be a null pointer.
— If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
— If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment.
If the value of argc is greater than one, the strings pointed to by argv1 through argv[argc-1] represent the program parameters.
— The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination
so, in short, adding the const is illegal and probably technically not possible (depending on the compiler)
Checking the standard you see the following rules: (ISO/IEC 9899:TC3), go to 5.1.2.2.1

Related

How to add multiple command line parameters to an executable C++ [duplicate]

In many C++ IDE's and compilers, when it generates the main function for you, it looks like this:
int main(int argc, char *argv[])
When I code C++ without an IDE, just with a command line compiler, I type:
int main()
without any parameters. What does this mean, and is it vital to my program?
argv and argc are how command line arguments are passed to main() in C and C++.
argc will be the number of strings pointed to by argv. This will (in practice) be 1 plus the number of arguments, as virtually all implementations will prepend the name of the program to the array.
The variables are named argc (argument count) and argv (argument vector) by convention, but they can be given any valid identifier: int main(int num_args, char** arg_strings) is equally valid.
They can also be omitted entirely, yielding int main(), if you do not intend to process command line arguments.
Try the following program:
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Have " << argc << " arguments:" << std::endl;
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
Running it with ./test a1 b2 c3 will output
Have 4 arguments:
./test
a1
b2
c3
argc is the number of arguments being passed into your program from the command line and argv is the array of arguments.
You can loop through the arguments knowing the number of them like:
for(int i = 0; i < argc; i++)
{
// argv[i] is the argument at index i
}
Suppose you run your program thus (using sh syntax):
myprog arg1 arg2 'arg 3'
If you declared your main as int main(int argc, char *argv[]), then (in most environments), your main() will be called as if like:
p = { "myprog", "arg1", "arg2", "arg 3", NULL };
exit(main(4, p));
However, if you declared your main as int main(), it will be called something like
exit(main());
and you don't get the arguments passed.
Two additional things to note:
These are the only two standard-mandated signatures for main. If a particular platform accepts extra arguments or a different return type, then that's an extension and should not be relied upon in a portable program.
*argv[] and **argv are exactly equivalent, so you can write int main(int argc, char *argv[]) as int main(int argc, char **argv).
int main();
This is a simple declaration. It cannot take any command line arguments.
int main(int argc, char* argv[]);
This declaration is used when your program must take command-line arguments. When run like such:
myprogram arg1 arg2 arg3
argc, or Argument Count, will be set to 4 (four arguments), and argv, or Argument Vectors, will be populated with string pointers to "myprogram", "arg1", "arg2", and "arg3". The program invocation (myprogram) is included in the arguments!
Alternatively, you could use:
int main(int argc, char** argv);
This is also valid.
There is another parameter you can add:
int main (int argc, char *argv[], char *envp[])
The envp parameter also contains environment variables. Each entry follows this format:
VARIABLENAME=VariableValue
like this:
SHELL=/bin/bash
The environment variables list is null-terminated.
IMPORTANT: DO NOT use any argv or envp values directly in calls to system()! This is a huge security hole as malicious users could set environment variables to command-line commands and (potentially) cause massive damage. In general, just don't use system(). There is almost always a better solution implemented through C libraries.
The parameters to main represent the command line parameters provided to the program when it was started. The argc parameter represents the number of command line arguments, and char *argv[] is an array of strings (character pointers) representing the individual arguments provided on the command line.
The main function can have two parameters, argc and argv. argc is an integer (int) parameter, and it is the number of arguments passed to the program.
The program name is always the first argument, so there will be at least one argument to a program and the minimum value of argc will be one. But if a program has itself two arguments the value of argc will be three.
Parameter argv points to a string array and is called the argument vector. It is a one dimensional string array of function arguments.
Lets consider the declaration:
int main (int argc, char *argv[])
In the above declaration, the type of the second parameter named argv is actually a char**. That is, argv is a pointer to a pointer to a char. This is because a char* [] decays to a char** due to type decay. For example, the below given declarations are equivalent:
int main (int argc, char *argv[]); //first declaration
int main (int argc, char **argv); //RE-DECLARATION. Equivalent to the above declaration
In other words, argv is a pointer that points to the first element of an array with elements of type char*. Moreover, each elements argv[i] of the array(with elements of type char*) itself point to a character which is the start of a null terminated character string. That is, each element argv[i] points to the first element of an array with elements of type char(and not const char). A diagram is given for illustration purposes:
As already said in other answers, this form of declaration of main is used when we want to make use of the command line argument(s).
The first parameter is the number of arguments provided and the second parameter is a list of strings representing those arguments.
Both of
int main(int argc, char *argv[]);
int main();
are legal definitions of the entry point for a C or C++ program. Stroustrup: C++ Style and Technique FAQ details some of the variations that are possible or legal for your main function.
In case you learn something from this
#include<iostream>
using namespace std;
int main(int argc, char** argv) {
cout << "This program has " << argc << " arguments:" << endl;
for (int i = 0; i < argc; ++i) {
cout << argv[i] << endl;
}
return 0;
}
This program has 3 arguments. Then the output will be like this.
C:\Users\user\Desktop\hello.exe
hello
people
When using int and char**, the first argument will be the number of commands in by which the programs is called and second one is all those commands
Just to add because someone says there is a third parameter (*envp[]), it's true, there is, but is not POSIX safe, if you want your program to use environment variables you should use extern char environ ;D

Dynamic 1D array as input

I am trying to get a dynamic 1D array of integers as input. The situation is I do not know how many inputs I would have. I have the following code, but I know its wrong. Could you please tell me how I can achieve this?
int main(string path,string aligned_path,vector<int>cams)
{
string path = "/home/iiith/resect/output.txt";
findpoints(cams,path);
}
The size of cams is actually unknown. I would not know how many cams they would provide as input. Am trying to achieve something like the below
./a.out path1 path2 1 2 3 5 6
The numbers trailing in the end would be the cams. it can be any number of cams. Is it possible to receive them all as input? is it possible to have an inut parameter that is dynamic as the above.? Please help me here. It would b really helpful. Thanks in Advance
Your definition of main is invalid. In C and C++, main has a strict definition (although arguments can be ignored if not used):
int main(int argc, char **argv)
A common extension is to also pass in environment variables:
int main(int argc, char **argv, char **envp)
and if arguments aren't used at all:
int main()
The arguments to main are defined as follows argc is the number of elements in the list of arguments. Each of the following argv[0] .. argv[argc-1] contain the arguments to your function. argv[0] is the name of the executable itself. argv[1] with your example would be path1.
So, you know how many cams there are based on argc. Of course, you have to copy the string values in argv[x] into the relevant place in a vector, using, perhaps, std::stoi(...) to make it into an integer value.
The signature of main must be int main(int argc, char* argv[]) (or equivalent, or int main()). You would process the arguments into something more useful within your own code. Here's a quick and sloppy example (no proper error handling, etc).
#include <iostream>
#include <cstdlib>
#include <vector>
int main(int argc, char * argv[])
{
std::vector<int> nums;
nums.reserve(argc-3);
int pos = 3;
// Read args into vector of ints
while (pos < argc)
{
nums.push_back(atoi(argv[pos]));
++pos;
}
// Print them
for (auto i : nums) std::cout << i << '\n';
}
Here's a run:
$ ./a.out path1 path2 1 2 3 5 4
1
2
3
5
4
Just in case it isn't clear: argc contains the number of arguments passed, including the name of the program. so for $ ./a.out argc=1, for $ ./a.out some list of args argc=5.
Then argv is an array of c-style strings (NUL-terminated const char *s) containing the text of each argument.
Note that strictly speaking the argv array is 1 longer than it needs to be, and the last entry is guaranteed to be a NULL pointer.
For Standard geeks, I don't have the proper C++ 2011 standard, this is from N3337:
3.6.1 Main function
...
2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a
return type of type int, but otherwise its type is
implementation-defined. All implementations shall allow both of the
following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In the latter form argc
shall be the number of arguments passed to the program from the
environment in which the program is run. If argc is nonzero these
arguments shall be supplied in argv[0] through argv[argc-1] as
pointers to the initial characters of null-terminated multibyte
strings (ntmbs s) (17.5.2.1.4.2) and argv[0] shall be the pointer to
the initial character of a ntmbs that represents the name used to
invoke the program or "". The value of argc shall be non-negative. The
value of argv[argc] shall be 0. [ Note: It is recommended that any
further (optional) parameters be added after argv. —end note ]

What happens when you don't follow the practice of argv and argc [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
main(int argc, char *argv[])
Main's Signature in C++
If i write:
int main(int argc, char** argv)
i get proper commandline input.
What would happen if i wrote say,
int main(int foo, double fooDouble, fooType FooVar)
Is this OS-dependent or does it depend on the compiler?
Given that it does compile, it will still only be called with the argc and argv arguments.
So your fooDouble will get the pointer value of argv, and FooVar will get whatever value is in that register/stack space used for that argument position (which may not have been initialized by the callee, so it may hold any undefined value).
This code doesn't even have to compile. If it does, undefined behaviour may occur.
The effect of adding a third (or fourth, or fifth...) argument to main indeed depends on the operating system. For instance, on Windows (and I believe on Unix as well) you can have a third argument which grants access to the environment variables:
int main( int argc, char **argv, char **env )
The C standard (BS ISO/IEC 9899:1999) gives two alternatives for main:
int main(void) { /* ... */ }
and
int main(int argc, char *argv[]) { /* ... */ }
It also allows equivalents, so an argv of char ** argv for example. Additional arguments are "neither blessed nor forbidden by the Standard". Such addtions will be compiler and runtime (not operating system) specific.
The arguments are passed by the C runtime, which calls main(). Passing any other type would be problematic on general environments like Windows and UNIX, so quite how you would expect to pass a double or fooType is beyond me.
Invoking a program from either a command-line or using interfaces like execve (UNIX) or CreateProcess (Win32) involves passing zero delimited strings. In theory you could hack it to pass a binary value and then cast it in main, provided it does not contain a '\0' anywhere except at the end, which would be challenging.
EDIT: it occurs to me that you can call main() from within your program - the well known obvuscated C code "The twelve days of Christmas" does this. In this case there is no reason why you can pass anything the prototype allows.

does c++ standard prohibit the void main() prototype?

In section 3.6.1.2 of both C++ Standard 1998 and 2003 editions,
An implementation shall not predefine the main function. This function shall not be overloaded. It shall
have a return type of type int, but otherwise its type is implementation-defined.
I am not a native English speaker.I do not sure what does"but otherwise" means.Whether it is to prohibit the other return type,or to give the right to C++ compiler writer?
So what's the answer?
The english you quote does prohibit declaring main to return void. It is allowing variation in the arguments that come in, but not in the return type.
Aaargh! Yes it does. The only return type allowed by the standard is int. To quote from section 3.6.1:
It shall have a return type of type
int, but otherwise its type is
implementation-defined.
meaning it could look like this:
int main( float f );
int main( int x, int y );
etc. etc.
The type contains more than just the return type. Hence, the return type must be int, but you are free considering the remaining argument, i.e. you may e.g., select between
int main()
and
int main(int argc, char **argv)
The standard is saying that the return type must be int, but that the rest of the type is up to the implementation. For example, you could make a standard-compliant (but not terribly useful) C++ compiler that used.
int main(int secondsSinceSystemStart, int myFavoriteNumber, char* aFunnyJoke)
From Wikipedia:
In C and C++, the function prototype of the main function looks like one of the following:
int main(void)
int main(int argc, char **argv)
The parameters argc, argument count, and argv, argument vector, respectively give the number and value of the program's command-line arguments. The names of argc and argv may be any valid identifier, but it is common convention to use these names. Other platform-dependent formats are also allowed by the C and C++ standards; for example, Unix (though not POSIX.1) and Microsoft Visual C++ have a third argument giving the program's environment, otherwise accessible through getenv in stdlib.h:
int main(int argc, char **argv, char **envp)
Mac OS X and Darwin have a fourth parameter containing arbitrary OS-supplied information, such as the path to the executing binary:
int main(int argc, char **argv, char **envp, char **apple)
As far as parameters are concern ,it allows
int main()
int main(int argc , char * argv[])
int main(int argc , char * argv[] , char * envr[])
But as per standard return type should be int for consistency purpose.
The intent is to say that aspects of the type of the main function other than the return type are implementation defined. That means this declaration is allowed by this clause of the standard:
int main(int fred, char *bouncy);
but not this one:
void main(int fred, char *bouncy);
Its return type must be int, but the implementation is allowed to have different argument types.

Defining own main functions arguments argc and argv

i want to create an object of type QApplication which needs the main functions arguments argc and argv as an input:
QApplication app(argc, argv);
Since i am within a user defined function without access to the main function i want to define this arguments on my own. I have tried several approaches but i cannot get the type conversion right. My last approach did not work either:
int argc = 1;
char **argv;
char arguments[1][12] = {{"cgalExample"}};
argv = arguments;
Thanks for any hint.
If you want to be insanely pendantic, then you want something like the following. The key points are that argv is not const, argv is NULL terminated, argc is the number of usable elements in argv including the program name. It is required to be modifiable so you cannot use string literals - argv[i] is required to point to a modifiable array of characters.
int my_main() {
char arg0[] = "programName";
char arg1[] = "arg";
char arg2[] = "another arg";
char* argv[] = { &arg0[0], &arg1[0], &arg2[0], NULL };
int argc = (int)(sizeof(argv) / sizeof(argv[0])) - 1;
QApplication the_application(argc, &argv[0]);
return the_application.run();
}
The Standard (ISO/IEC 9899:1999 section 5.1.2.2.1) states that the following is true about argc and argv in a hosted environment:
The value of argc shall be nonnegative.
argv[argc] shall be a null pointer.
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[0] through argv[argc-1] represent program parameters.
The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
QApplication states the following:
Warning: The data referred to by argc and argv must stay valid for the
entire lifetime of the QApplication
object. In addition, argc must be
greater than zero and argv must
contain at least one valid character
string.
…
Note: argc and argv might be changed
as Qt removes command line arguments
that it recognizes.
Quick and dirty, but working for QApplication:
char *argv[] = {"program name", "arg1", "arg2", NULL};
int argc = sizeof(argv) / sizeof(char*) - 1;
For a more complete and C standard conforming solution see D.Shawley's answer.
Why your solution doesn't work is simple:
array[i][j] results in a i*j matrix. But what you actually want is an array with pointers to strings in it.
Why are you concerning your self with the size of the text in argv, I would just let the compiler do it:
int argc = 1;
char* argv[] = {"Hello Qt!"}; // exactly as it is defined in main
How about...
int argc = 2;
const char* argv[] ={"program","first-argument"};
...or if you need them to be non-const...
int argc = 2;
char* argv[] ={strdup("program"),strdup("first-argument")};
Although neither the C nor C++ standard requires it, most compilers make the arguments to main available to you as _argv and _argc. If memory serves POSIX requires this. Anyway, you need to use something like:
extern int _argc;
extern char *_argv[];
and from there you can use them about like normal.
I hope this works:
char* argv[1];
argv[0] = "cgalExample";