By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,221 Members | 1,663 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,221 IT Pros & Developers. It's quick & easy.

argv/pointer problems

P: n/a
Sorry in advance if this is a stupid question - I am new to C++.

In the process of converting program to be run from the command line
into a function to be run from another program I noticed behaviour
that I do not understand. Consider the example programs below:

Program 1 below is a simple program that merely outputs the command
line arguments. This compiles and runs fine with Microsoft Visual C++
6.0 and g++ 3.3.1.

Program 2 brings up a compile time error in both; in MVC++ it is

"test_cline_2.cpp: In function `int main()':
test_cline_2.cpp:19: error: non-lvalue in increment",

and in g++ it is

"test_cline_2.cpp(19) : error C2105: '++' needs l-value".

Program 3 compiles and runs fine.

Can anyone tell me why Program 2 does not compile? A friend has tried
the code on C++ .NET and apparently it *did* compile.

Thanks in advance,

Robin Sanderson

-----

//Program 1
#include <iostream>
using std:: cout; using std::endl;

int main(int argc, char * argv[])
{
int i;

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

-----

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}

void vFunction(int argc, char ** argv)
{
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}
Jul 22 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Robin Sanderson wrote:
Sorry in advance if this is a stupid question - I am new to C++.

In the process of converting program to be run from the command line
into a function to be run from another program I noticed behaviour
that I do not understand. Consider the example programs below:

Program 1 below is a simple program that merely outputs the command
line arguments. This compiles and runs fine with Microsoft Visual C++
6.0 and g++ 3.3.1.

Program 2 brings up a compile time error in both; in MVC++ it is

"test_cline_2.cpp: In function `int main()':
test_cline_2.cpp:19: error: non-lvalue in increment",

and in g++ it is

"test_cline_2.cpp(19) : error C2105: '++' needs l-value".

Program 3 compiles and runs fine.

Can anyone tell me why Program 2 does not compile? A friend has tried
the code on C++ .NET and apparently it *did* compile.

Thanks in advance,

Robin Sanderson

-----

//Program 1
#include <iostream>
using std:: cout; using std::endl;

int main(int argc, char * argv[])
{
int i;

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}
In this program, argv is a pointer.

-----

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}
In this program, argv is an array. You can't increment an array.
-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}

void vFunction(int argc, char ** argv)
{
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}


Here, argv is again a pointer.

--
2 hours? Boy, that's way too old. You should use a more recent version.
(Waldo Bastian about a copile error in a 2 hours old CVS version of KDE)

Jul 22 '05 #2

P: n/a
Thanks, Rolf. Can anyone explain why the code runs on .NET?
Jul 22 '05 #3

P: n/a
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3? Is it possible to declare argv as a pointer
in Program 2 (so it can be used in an identical way as in the other
programs)?

Thanks,

Robin

-----

//Program 3
#include <iostream>
using std:: cout; using std::endl;

void vFunction(int argc,char * argv[]);

int main()
{
int iInt;
char * cArray[4];

iInt=3;
cArray[0] = "program_name";
cArray[1] = "argument_1";
cArray[2] = "argument_2";
cArray[3] = NULL;

vFunction(iInt,cArray);

return 0;
}
void vFunction(int argc, char * argv[]) {
int i;

cout << "Using argv++:" << endl;
for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}
cout << endl;

return;
}

Jul 22 '05 #4

P: n/a
Robin Sanderson wrote:
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3?
In program 3, it's a parameter, while in program 2, it's a local
variable. You cannot pass arrays as parameters to functions, and
therefore, a "convenience" was added to C (and inherited to C++). If
you write a parameter in a form that looks like an array, it will
actually be a pointer. That's btw the reason why you can leave out the
size. When defining an array, you _always_ need a size for it.
Is it possible to declare argv as a pointer in Program 2 (so it can be
used in an identical way as in the other programs)?

int main()
{
int i;

int argc=3;
char * args[3];

args[0] = "program_name";
args[1] = "argument_1";
args[2] = "argument_2";

char * (*argv) = args;
// declares argv as a pointer to the array args

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

Jul 22 '05 #5

P: n/a

"Robin Sanderson" <ro*************@orange.net> wrote in message
news:3a**************************@posting.google.c om...
I have just noticed that I posted the wrong version of Programm 3 -
the "** argv" should have been "* argv[]", and this is corrected below
- although this does not alter whether or not it compiles.

This may be a(nother) daft question, but what is it that makes the
difference between the use of "char * argv[3]" in Program 2 and "char
* argv[]" in Program 3?
The first is an array, the second is a pointer. Even though you say char*
argv[], it is a pointer. Using [] in a function parameter is just another
way of declaring a pointer (in other words [] is a lie, it looks like an
array but it isn't). There is no way to have an array as a function
parameter. So the real difference is that in one case argv is a function
parameter (no arrays allowed) and in the second case argv is a local
variable (arrays are allowed).
Is it possible to declare argv as a pointer
in Program 2 (so it can be used in an identical way as in the other
programs)?


Sure, one way would be

int argc=3;
char * argv_array[3];
char ** argv = argv_array;

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

john
Jul 22 '05 #6

P: n/a
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

argv is of type char* const. You can't change it's value.


char * argv[3];

char * pCurrent = argv;

pCurrent++;

-JKop
Jul 22 '05 #7

P: n/a
JKop posted:
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl; argv++; }

return 0;
}

argv is of type char* const. You can't change it's value.


char * argv[3];

char * pCurrent = argv;

pCurrent++;


OOPS!!!!

char ** pCurrent = argv;

-JKop
Jul 22 '05 #8

P: n/a
JKop wrote:
Robin Sanderson posted:

//Program 2
#include <iostream>
using std:: cout; using std::endl;

int main()
{
int i;

int argc=3;
char * argv[3];

argv[0] = "program_name";
argv[1] = "argument_1";
argv[2] = "argument_2";

for(i=0;i<argc;i++)
{
cout << "i="<<i<<"; *argv = " << *argv << endl;
argv++;
}

return 0;
}

argv is of type char* const.


No, it isn't. it's of type array of type char* with 3 elements.

Jul 22 '05 #9

P: n/a
Thanks Rolf and John for your clear explanations. I have to admit I
still don't understand why Program 2 compiled and ran on .NET, but
otherwise I am starting to get the hang of this C++ pointer-malarkey.

Thanks again,

Robin
Jul 22 '05 #10

P: n/a
JKop <NU**@NULL.NULL> wrote:
Robin Sanderson posted:
int main()
{
int i;

int argc=3;
char * argv[3];

argv is of type char* const. You can't change it's value.

No, argv's type is " array[3] of char* ". When used in an expression
like argv++ it is equivalent to &argv[0], which has type " char ** ".
There is no "const" anywhere. argv is a non-modifiable lvalue (which
is a distinct concept from "const"). Another example of a non-modifiable
lvalue is the address of a builtin type; the following code won't
compile for the same reason:
int x;
++ &x;
or
(&x) = 0;
Jul 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.