473,480 Members | 2,333 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

modifying the strings pointed to by argv

The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?

Mar 14 '07 #1
56 4397
su**************@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
What can be the maximum length of such a string that is copied ?
0, if you have lots of sense. If you have only a little sense, then find
out how long the existing string is, and don't exceed that value. If
you have no sense whatsoever, pay no attention to either of the above
suggestions.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 14 '07 #2
On 14 Mar, 13:19, Richard Heathfield <r...@see.sig.invalidwrote:
subramanian10...@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
Well, possibly, but there's no particularly good reason I can see for
the arguments passed to your function to be read-only. It could
potentially be useful to space-trim or similar the input arguments and
certainly there's at least one (admittedly sub-optimal) unix[1] hack
involving modifying the argv[] values so that program arguments do not
appear in the ps process listing.

Can you clear up why you think this functionality is unwise ?
[1] Granted, slightly off-topic here, but then again there's a good
few things in the C standard that are that way to avoid breaking how
existng code works, so I'd like to apply for a temporary on-topic
licence for this discussion.


Mar 14 '07 #3
On Mar 14, 9:09*pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?
Well. There is still something to be clarify.

The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argv array
_itself_ is _not_ required to be modifiable.

The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buf[2] = {0};
strcpy(argv[1], buf);
return 0;
}

I guess making that modifiable may be considered for exec*() functions
or for the recursion of main(). And the maximum length maybe found in
POSIX.

Mar 14 '07 #4
On Mar 14, 6:41*pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:09*pm, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?

Well. There is still something to be clarify.

The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argv array
_itself_ is _not_ required to be modifiable.

The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
* * * * char buf[2] = {0};
* * * * strcpy(argv[1], buf);
* * * * return 0;

}

I guess making that modifiable may be considered for exec*() functions
or for the recursion of main(). And the maximum length maybe found in
POSIX.
No. in VC++ 2005 Express Edition, it allows us to copy, say, "test
message" onto argv[0] itself. Prior to modification argv[0] happened
to be the execautable name. Anyway, I just asked this question for
learning purpose.

Mar 14 '07 #5
On Mar 14, 9:51*pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
On Mar 14, 6:41*pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:09*pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?
Well. There is still something to be clarify.
The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argvarray
_itself_ is _not_ required to be modifiable.
The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
* * * * char buf[2] = {0};
* * * * strcpy(argv[1], buf);
* * * * return 0;
}
I guess making that modifiable may be considered for exec*() functions
or for the recursion of main(). And the maximum length maybe found in
POSIX.

No. in VC++ 2005 Express Edition, it allows us to copy, say, "test
message" onto argv[0] itself. Prior to modification argv[0] happened
to be the execautable name. Anyway, I just asked this question for
learning purpose.
No for what?

Copying "test message" onto argv[0] is _not_ modifying argv[0] itself,
only changing the contents of the array which argv[0] points to.
What's more, copying to argv[0] is UB.

Mar 14 '07 #6
On Mar 14, 7:13*pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:51*pm, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
On Mar 14, 6:41*pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:09*pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?
Well. There is still something to be clarify.
The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argv array
_itself_ is _not_ required to be modifiable.
The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
* * * * char buf[2] = {0};
* * * * strcpy(argv[1], buf);
* * * * return 0;
}
I guess making that modifiable may be considered for exec*() functions
or for the recursion of main(). And the maximum length maybe found in
POSIX.
No. in VC++ 2005 Express Edition, it allows us to copy, say, "test
message" onto argv[0] itself. Prior to modification argv[0] happened
to be the execautable name. Anyway, I just asked this question for
learning purpose.

No for what?

Copying "test message" onto argv[0] is _not_ modifying argv[0] itself,
only changing the contents of the array which argv[0] points to.
What's more, copying to argv[0] is UB.- Hide quoted text -

- Show quoted text -
I am sorry. Entire post of mine in this thread is wrong.

Mar 14 '07 #7
On Mar 14, 1:41 pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:09 pm, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?

Well. There is still something to be clarify.

The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argv array
_itself_ is _not_ required to be modifiable.
This came up on comp.std.c again recently. The intent is that the argv
array itself /is/ required to be modifiable, and the actual wording of
the standard can be argued to require the same.

Mar 14 '07 #8
On Mar 14, 6:19 am, Richard Heathfield <r...@see.sig.invalidwrote:
subramanian10...@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
As with many aspects of Standard C it was to support common pre-
existing practice. In UNIXes of the time the ps command could be used
to view the current argv data. Programs made use of this facility
either to hide the parameters they were invoked with (for example, if
a password was passed as a command line option) or to make application
status information available through ps (sendmail did this if I
remember correctly). I don't know if modern UNIXes and similar still
use this.

Mar 14 '07 #9
Cong Wang wrote:
>
.... snip ...
>
The standard just says "argc and argv and the strings pointed to
by the argv array shall be modifiable by the program." But the
argv array _itself_ is _not_ required to be modifiable.
^^^
I fail to understand why this char-set cannot include the normal
coding for 'f' and 'i', thus causing abnormal displays.
>
The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buf[2] = {0};
strcpy(argv[1], buf);
return 0;
}

I guess making that modifiable may be considered for exec*()
functions or for the recursion of main(). And the maximum length
maybe found in POSIX.
There are _no_ restrictions against modifying argv and argc. After
all, those are values local to main. The only restrictions are
against modifying *argv (forbidden) and *argv[i] (for i <= argc),
which is not allowed to extend the length of the string argv[i].
So this has nothing to do with any possible recursive call to main.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 14 '07 #10
"su**************@yahoo.com, India" wrote:
>
On Mar 14, 6:41 pm, "Cong Wang" <xiyou.wangc...@gmail.comwrote:
On Mar 14, 9:09 pm, "subramanian10...@yahoo.com, India"

<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?
Well. There is still something to be clarify.

The standard just says "argc and argv and the strings pointed to by
the argv array shall be modifiable by the program." But the argv array
_itself_ is _not_ required to be modifiable.

The following buggy code only works well when argc >=2 and
strlen(argv[1]) >=1:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
char buf[2] = {0};
strcpy(argv[1], buf);
return 0;

}

I guess making that modifiable may be considered for exec*() functions
or for the recursion of main(). And the maximum length maybe found in
POSIX.

No. in VC++ 2005 Express Edition, it allows us to copy, say, "test
message" onto argv[0] itself. Prior to modification argv[0] happened
to be the execautable name. Anyway, I just asked this question for
learning purpose.
VC is a specific implementation, and has nothing to do with
validity of the operation. In fact there is a large probability
that the above action contravenes the standard. It depends on the
actual values of argc (0) and argv (non-NULL, with
strlen(argv[0]) >= strlen("test message")). Modifying the actual
value of argv[0] (a pointer) is not allowed.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Mar 14 '07 #11
Bryan said:
On 14 Mar, 13:19, Richard Heathfield <r...@see.sig.invalidwrote:
>subramanian10...@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1],
etc. Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.

Well, possibly, but there's no particularly good reason I can see for
the arguments passed to your function to be read-only.
Can you give me a particularly good reason for modifying them? I can
think of none. Oh, wait a minute...
It could
potentially be useful to space-trim or similar the input arguments and
certainly there's at least one (admittedly sub-optimal) unix[1] hack
involving modifying the argv[] values so that program arguments do not
appear in the ps process listing.
....still struggling to see a /good/ reason. The ps thing is beyond the
scope of this discussion. This strikes me as a shell issue rather than
an argv issue. But as for space-trimming the input arguments, why not
leave them in peace and just copy out the bits you need?
Can you clear up why you think this functionality is unwise ?
I consider it to be unwarranted chumminess with the start-up code.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 14 '07 #12
Richard Heathfield wrote:
Bryan said:
On 14 Mar, 13:19, Richard Heathfield <r...@see.sig.invalidwrote:
subramanian10...@yahoo.com, India said:

The standard allows that we can copy strings onto arg[0], arg[1],
etc. Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
Well, possibly, but there's no particularly good reason I can see for
the arguments passed to your function to be read-only.

Can you give me a particularly good reason for modifying them?
An extended getopt function. If a program is called as './program a -r
b' and -r is to be considered an option, the function (with an already
standardised interface) needs to make sure that after the options are
read, argv[2] points to "a", and argv[3] points to "b", so that the
rest of the program can simply process all non-option arguments one by
one up to the last.

Mar 14 '07 #13
In article <Je******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Well, possibly, but there's no particularly good reason I can see for
the arguments passed to your function to be read-only.
>Can you give me a particularly good reason for modifying them? I can
think of none. Oh, wait a minute...
>It could
potentially be useful to space-trim or similar the input arguments and
certainly there's at least one (admittedly sub-optimal) unix[1] hack
involving modifying the argv[] values so that program arguments do not
appear in the ps process listing.
>...still struggling to see a /good/ reason.
Another use on some systems is to cause ps-like programs to display
some useful status information about the running program.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Mar 14 '07 #14
Richard Heathfield wrote:
Bryan said:
Well, possibly, but there's no particularly good reason I can see
for the arguments passed to your function to be read-only.

Can you give me a particularly good reason for modifying them? I can
think of none.
One thing that comes to mind is that you could pass the arg strings to
strtok() without having to make a copy. I don't know that this
qualifies as a good reason, but it's possibly a reason for requiring
that.

I've never personally run across a "use case".


Brian
Mar 14 '07 #15
On 14 Mar 2007 06:09:01 -0700, in comp.lang.c ,
"su**************@yahoo.com, India" <su**************@yahoo.com>
wrote:
>The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
To save you having to create a copy. Remember, C was written for a
machine with a _very_ small amount of memory by today's standards.
>What can be the maximum length of such a string that is copied ?
Naturally, you can't copy anything larger than the original length of
the the argument.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 14 '07 #16
CBFalconer <cb********@yahoo.comwrites:
Cong Wang wrote:
>>
... snip ...
>>
The standard just says "argc and argv and the strings pointed to
by the argv array shall be modifiable by the program." But the
argv array _itself_ is _not_ required to be modifiable.
^^^
I fail to understand why this char-set cannot include the normal
coding for 'f' and 'i', thus causing abnormal displays.
[...]

It's a ligature. In typesettings, it's common for certain pairs of
letters, such as "fl" or "fi", to be joined into a single glyph.

The "fi" in "modifiable" appears as a ligature in my copy of
n1124.pdf, but as two separate letters when I copy-and-paste it. I've
had problems in the past with copy-and-pasting ligatures but I can't
reproduce it at the moment.

See <http://en.wikipedia.org/wiki/Typographical_ligaturefor more
information on ligatures. (I'm assuming the article is accurate; if
it isn't, it's good enough to fool me.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 15 '07 #17
On Mar 14, 3:19 pm, Richard Heathfield <r...@see.sig.invalidwrote:
subramanian10...@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
Why ? Just because you don't like it ?

And any reason you may give why assume that program arguments are
'naturally'
read-only is off-topic here, since they are part of the OS/shell
interface.

Mar 15 '07 #18
Racaille said:
On Mar 14, 3:19 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>subramanian10...@yahoo.com, India said:
The standard allows that we can copy strings onto arg[0], arg[1],
etc. Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.

Why ? Just because you don't like it ?
I have this innate tendency not to like stupid ideas (except, perhaps,
democracy, for which I retain a certain fondness).

And any reason you may give why assume that program arguments are
'naturally' read-only is off-topic here, since they are part of the
OS/shell interface.
What on earth are you smoking? Of course the nature of main()'s
arguments is topical here!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 15 '07 #19
On Mar 15, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.
Why ? Just because you don't like it ?

I have this innate tendency not to like stupid ideas (except, perhaps,
democracy, for which I retain a certain fondness).
I don't care about your mildly conservative opinions about democracy.
(In fact, I find them insulting, but this is off-topic here).
And any reason you may give why assume that program arguments are
'naturally' read-only is off-topic here, since they are part of the
OS/shell interface.

What on earth are you smoking? Of course the nature of main()'s
arguments is topical here!
Please a) be polite b) explain what you understand by the 'nature' of
main()'s arguments. 'char **argv' is not different from 'char **foo',
and
the way the OS, dynamic linker, etc manages to call main() and to
construct its argument list is not specified by any standard.

Mar 15 '07 #20
On Mar 14, 10:59 pm, CBFalconer <cbfalco...@yahoo.comwrote:
The only restrictions are
against modifying *argv (forbidden) and *argv[i] (for i <= argc),
which is not allowed to extend the length of the string argv[i].
So this has nothing to do with any possible recursive call to main.
could you please point where those restrictions are in the standard ?
I read n869 / 5.1.2.2.1 and found nothing like that.

At the contrary, modifying *argv[i] (for i < argc, '<' not '<=')
is explicitly allowed.
Mar 15 '07 #21
Racaille said:
On Mar 15, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Good question. Why indeed? It's a stupid stupid stupid idea, if
ever there was one.
Why ? Just because you don't like it ?

I have this innate tendency not to like stupid ideas (except,
perhaps, democracy, for which I retain a certain fondness).

I don't care about your mildly conservative opinions about democracy.
(In fact, I find them insulting, but this is off-topic here).
If you look for insults, you will find them everywhere.
And any reason you may give why assume that program arguments are
'naturally' read-only is off-topic here, since they are part of the
OS/shell interface.

What on earth are you smoking? Of course the nature of main()'s
arguments is topical here!

Please a) be polite
I *am* being polite. You can try for impolite if you like.
b) explain
No chance. This is my last reply to you (at least for as long as I
remember). I've already stopped replying to Mr Muntyan for much the
same reason. When you guys get a clue, let me know.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 15 '07 #22
Richard Heathfield wrote:
Racaille said:
>On Mar 15, 4:09 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>>>Good question. Why indeed? It's a stupid stupid stupid idea, if
ever there was one.
Why ? Just because you don't like it ?
I have this innate tendency not to like stupid ideas (except,
perhaps, democracy, for which I retain a certain fondness).
I don't care about your mildly conservative opinions about democracy.
(In fact, I find them insulting, but this is off-topic here).

If you look for insults, you will find them everywhere.
>>>And any reason you may give why assume that program arguments are
'naturally' read-only is off-topic here, since they are part of the
OS/shell interface.
What on earth are you smoking? Of course the nature of main()'s
arguments is topical here!
Please a) be polite

I *am* being polite. You can try for impolite if you like.
>b) explain

No chance. This is my last reply to you (at least for as long as I
remember). I've already stopped replying to Mr Muntyan for much the
same reason.
For the reason you hate anyone disagreeing with you? Or that you
hate anyone who doesn't agree that you're being kind and nice at
every moment? Man, this very thread shows how funny it is:

R: Where are no non-stupid reasons to do this.
O: Hacking to make ps display funny stuff.
R: Off-topic here, hence the above statement was
right, I was right as usual.

You love to apply "off-topic" as a last measure if you can't use
logic to shave opponent off, indeed. Your politeness is another
funny thing.
When you guys get a clue, let me know.
I did, indeed.

Yevgen
Mar 15 '07 #23
On Thu, 15 Mar 2007 14:09:25 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Racaille said:
>On Mar 14, 3:19 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>subramanian10...@yahoo.com, India said:

The standard allows that we can copy strings onto arg[0], arg[1],
etc. Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if ever
there was one.

Why ? Just because you don't like it ?

I have this innate tendency not to like stupid ideas (except, perhaps,
democracy, for which I retain a certain fondness).
Okay, but setting aside tautological arguments, why?
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 15 '07 #24
Mark McIntyre said:
>>On Mar 14, 3:19 pm, Richard Heathfield <r...@see.sig.invalidwrote:
subramanian10...@yahoo.com, India said:

The standard allows that we can copy strings onto arg[0], arg[1],
etc. Why is it allowed ?

Good question. Why indeed? It's a stupid stupid stupid idea, if
ever there was one.
<snip>
Okay, but setting aside tautological arguments, why?
The risk to the stability of your program is potentially high, and you
gain nothing that you can't get more safely in some other way.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #25
On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
The risk to the stability of your program is potentially high,
How so?
and you
gain nothing that you can't get more safely in some other way.
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Mar 16 '07 #26
Fr************@googlemail.com said:
On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>The risk to the stability of your program is potentially high,

How so?
If you screw up and write too much into an argv array, you're far more
likely to trash something important than if you wrote too much into
some other array. (That doesn't mean it's okay to write too much into
some other array, of course.)
>and you
gain nothing that you can't get more safely in some other way.

But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.
<shrugThat particular game is not, in my view, worth the candle.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #27
Fr************@googlemail.com writes:
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.
I've yet to see one of these that is not better written some
other way.
--
"When I have to rely on inadequacy, I prefer it to be my own."
--Richard Heathfield
Mar 16 '07 #28
On Mar 15, 11:22 pm, Ben Pfaff <b...@cs.stanford.eduwrote:
Francine.Ne...@googlemail.com writes:
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.

I've yet to see one of these that is not better written some
other way.
How about this little factorial program? I think it's pretty cute.
E.g.
$ ./factorial 4
24
#include <stdio.h>
#include <stdlib.h>

struct s {
unsigned int f;
unsigned int n;
};

main(int argc, char **argv)
{
unsigned int i;
if(*argv) {
i=(unsigned int) atoi(argv[1]);
*argv=0;
argv[1]=malloc(sizeof(struct s));
((struct s*) argv[1])->n=i;
((struct s*) argv[1])->f=1;
}

if(((struct s*) argv[1])->n) {
((struct s*) argv[1])->f*=((struct s*) argv[1])->n--;
main(argc,argv);
return 0;
}
printf("%u\n",((struct s*) argv[1])->f);
free(argv[1]);
return 0;
}

Mar 16 '07 #29
On Mar 15, 11:16 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Francine.Ne...@googlemail.com said:
On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
The risk to the stability of your program is potentially high,
How so?

If you screw up and write too much into an argv array, you're far more
likely to trash something important than if you wrote too much into
some other array. (That doesn't mean it's okay to write too much into
some other array, of course.)
Isn't there a school of thought that says that if you screw up it's
better to have something blow up in your face immediately, rather than
leaving a subtle, hard-to-trace bug waiting somewhere to be discovered
intermittently at some unknown future date?
and you
gain nothing that you can't get more safely in some other way.
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.

<shrugThat particular game is not, in my view, worth the candle.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Mar 16 '07 #30
On Thu, 15 Mar 2007 22:59:48 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Mark McIntyre said:
>Okay, but setting aside tautological arguments, why?

The risk to the stability of your program is potentially high, and you
gain nothing that you can't get more safely in some other way.
What risk?
Sorry to go on about this, but to date I'm not aware of anyone in this
thread actually producing some evidence that this is bad. After all,
argv[n] is just another array of chars, so long as you don't walk off
the end of it, there's no more risk than with any other array of
chars.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 16 '07 #31
On Thu, 15 Mar 2007 23:16:18 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Fr************@googlemail.com said:
>On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>The risk to the stability of your program is potentially high,

How so?

If you screw up and write too much into an argv array, you're far more
likely to trash something important than if you wrote too much into
some other array.
C&V please.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 16 '07 #32
Fr************@googlemail.com writes:
On Mar 15, 11:22 pm, Ben Pfaff <b...@cs.stanford.eduwrote:
>Francine.Ne...@googlemail.com writes:
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.

I've yet to see one of these that is not better written some
other way.

How about this little factorial program? I think it's pretty cute.
It's a 28-line program (including blank lines and #includes) that
uses 7 casts. Not my idea of "cute".
--
"This is a wonderful answer.
It's off-topic, it's incorrect, and it doesn't answer the question."
--Richard Heathfield
Mar 16 '07 #33
Fr************@googlemail.com said:
On Mar 15, 11:16 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Francine.Ne...@googlemail.com said:
On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalid>
wrote:
The risk to the stability of your program is potentially high,
How so?

If you screw up and write too much into an argv array, you're far
more likely to trash something important than if you wrote too much
into some other array. (That doesn't mean it's okay to write too much
into some other array, of course.)

Isn't there a school of thought that says that if you screw up it's
better to have something blow up in your face immediately, rather than
leaving a subtle, hard-to-trace bug waiting somewhere to be discovered
intermittently at some unknown future date?
Yes, absolutely, but C doesn't offer any guarantee that trashing
something important will get you an immediate blow-up at a time
convenient to you.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #34
Mark McIntyre said:
On Thu, 15 Mar 2007 22:59:48 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>>Mark McIntyre said:
>>Okay, but setting aside tautological arguments, why?

The risk to the stability of your program is potentially high, and you
gain nothing that you can't get more safely in some other way.

What risk?
Sorry to go on about this, but to date I'm not aware of anyone in this
thread actually producing some evidence that this is bad. After all,
argv[n] is just another array of chars, so long as you don't walk off
the end of it, there's no more risk than with any other array of
chars.
You're right. As long as your code is perfect, nothing bad can happen.

Gosh. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #35
Fr************@googlemail.com said:
On Mar 15, 11:22 pm, Ben Pfaff <b...@cs.stanford.eduwrote:
>Francine.Ne...@googlemail.com writes:
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.

I've yet to see one of these that is not better written some
other way.

How about this little factorial program? I think it's pretty cute.
<snip>

Here are some results from that program:

../foo
Segmentation fault (core dumped)
../foo -h
1
../foo 0 /* it actually gets this right, which was a mild surprise */
1

Every non-negative integer argument up to and including 12 works fine,
but observe what happens when we exceed 12:

../foo 13
1932053504

(the correct value is of course 6227020800).

So you have a seriously convoluted program which only works for a
vanishingly small percentage (less than 0.2%) of possible valid inputs.
My own factorial program is, alas, twice as long as yours (58 lines),
not including library code of course - but it continues to get the
answers right long past 13, despite not taking advantage of ISO's
licence to write into argv. For example, compare this:

../foo 52
0

with this:

~/path/to/rjhfactorial 52
80658175170943878571660636856403766975289505440883 277824000000000000

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #36
On Mar 16, 1:43 am, Ben Pfaff <b...@cs.stanford.eduwrote:
Francine.Ne...@googlemail.com writes:
On Mar 15, 11:22 pm, Ben Pfaff <b...@cs.stanford.eduwrote:
Francine.Ne...@googlemail.com writes:
But, for example, small programs can sometimes be written in a very
elegant way by calling main() recursively, possibly modifying its
parameters between calls.
I've yet to see one of these that is not better written some
other way.
How about this little factorial program? I think it's pretty cute.

It's a 28-line program (including blank lines and #includes) that
uses 7 casts. Not my idea of "cute".
I suppose one could #define CAST (struct s*) to make the code look
prettier.
--
"This is a wonderful answer.
It's off-topic, it's incorrect, and it doesn't answer the question."
--Richard Heathfield

Mar 16 '07 #37
On Mar 16, 5:05 am, Richard Heathfield <r...@see.sig.invalidwrote:
./foo
Segmentation fault (core dumped)
./foo -h
1
Well, of course, you could bloat the code with error messages, but
there's the old saying, Garbage In Garbage Out (GIGO).
./foo 0 /* it actually gets this right, which was a mild surprise */
1

Every non-negative integer argument up to and including 12 works fine,
but observe what happens when we exceed 12:

./foo 13
1932053504

(the correct value is of course 6227020800).
Well, you can modify the struct to maintain the factorial as a long
long if you want...
So you have a seriously convoluted program which only works for a
vanishingly small percentage (less than 0.2%) of possible valid inputs.
My own factorial program is, alas, twice as long as yours (58 lines),
not including library code of course - but it continues to get the
answers right long past 13, despite not taking advantage of ISO's
licence to write into argv. For example, compare this:

./foo 52
0

with this:

~/path/to/rjhfactorial 52
80658175170943878571660636856403766975289505440883 277824000000000000
....or even to use GMP or some other library, and it will then work for
100% of valid inputs. This was just a proof of concept - like anything
it can be extended and generalized out of sight.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #38
Mark McIntyre <ma**********@spamcop.netwrote:
On Thu, 15 Mar 2007 22:59:48 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
Mark McIntyre said:
Okay, but setting aside tautological arguments, why?
The risk to the stability of your program is potentially high, and you
gain nothing that you can't get more safely in some other way.

What risk?
Sorry to go on about this, but to date I'm not aware of anyone in this
thread actually producing some evidence that this is bad. After all,
argv[n] is just another array of chars, so long as you don't walk off
the end of it, there's no more risk than with any other array of
chars.
Well, he seems to think that we're all going to make like C++
programmers and forget about "so long as". The natural solution to this
disease is not, however, to forbid writing to argv[n], but to make
arrays in C size-limited, with run-time checks on transgressions
thereof, and a sizeofobject operator for pointers (and arrays decayed
into pointers), including any which are passed as function parameters.
Unfortunately this is a lot of work, but there _is_ previous art in this
area; I suggest that he get together with jacob navia.

Richard, g,d,rlb
Mar 16 '07 #39
On Fri, 16 Mar 2007 04:50:23 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Mark McIntyre said:
After all,
>argv[n] is just another array of chars, so long as you don't walk off
the end of it, there's no more risk than with any other array of
chars.

You're right. As long as your code is perfect, nothing bad can happen.
But this is axiomatic. By this logic, one would never write to
character arrays at all.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 16 '07 #40
Mark McIntyre said:
By this logic, one would never write to character arrays at all.
It's a deal. We're probably still in time for the next Standard - are
you going to write up the DR or shall I? :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 16 '07 #41
Racaille wrote:
CBFalconer <cbfalco...@yahoo.comwrote:
>The only restrictions are
against modifying *argv (forbidden) and *argv[i] (for i <= argc),
which is not allowed to extend the length of the string argv[i].
So this has nothing to do with any possible recursive call to main.

could you please point where those restrictions are in the standard
? I read n869 / 5.1.2.2.1 and found nothing like that.

At the contrary, modifying *argv[i] (for i < argc, '<' not '<=')
is explicitly allowed.
N869 states:

-- 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.

and specifically omits any permission to modify the argv array.
The string length restrictions are just common sense.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 16 '07 #42
Mark McIntyre wrote:
Richard Heathfield <rj*@see.sig.invalidwrote:
>Fr************@googlemail.com said:
>>Richard Heathfield <r...@see.sig.invalidwrote:

The risk to the stability of your program is potentially high,

How so?

If you screw up and write too much into an argv array, you're far
more likely to trash something important than if you wrote too
much into some other array.

C&V please.
No such, just common sense. Those variables are setup before
entering main, so they are likely to be surrounded by sensitive
system data, which you can mung.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 16 '07 #43
Richard Heathfield wrote:
Fr************@googlemail.com said:
>On Mar 15, 11:22 pm, Ben Pfaff <b...@cs.stanford.eduwrote:
>>Francine.Ne...@googlemail.com writes:

But, for example, small programs can sometimes be written in a
very elegant way by calling main() recursively, possibly
modifying its parameters between calls.

I've yet to see one of these that is not better written some
other way.

How about this little factorial program? I think it's pretty cute.

<snip>

Here are some results from that program:

./foo
Segmentation fault (core dumped)
./foo -h
1
./foo 0 /* it actually gets this right, which was a mild surprise */
1

Every non-negative integer argument up to and including 12 works
fine, but observe what happens when we exceed 12:

./foo 13
1932053504

(the correct value is of course 6227020800).

So you have a seriously convoluted program which only works for a
vanishingly small percentage (less than 0.2%) of possible valid inputs.
My own factorial program is, alas, twice as long as yours (58 lines),
not including library code of course - but it continues to get the
answers right long past 13, despite not taking advantage of ISO's
licence to write into argv. For example, compare this:

./foo 52
0

with this:

~/path/to/rjhfactorial 52
80658175170943878571660636856403766975289505440883 277824000000000000
Mine produces <grin:

[1] c:\c\junk>fact 52
Factorial(52) == 2147483648e12 * pow(3,23) * pow(7,8) * pow(11,4) *
pow(13,4) *
pow(17,3) * pow(19,2) * pow(23,2) * pow(29,1) * pow(31,1) *
pow(37,1) * pow(41,1
) * pow(43,1) * pow(47,1) * pow(2,6)
or approximately
80658175170943876840000000000000000000000000000000 0000000000000
00000.

without any fancy bignum arithmetic packages.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 16 '07 #44
On Mar 14, 1:09 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.comwrote:
The standard allows that we can copy strings onto arg[0], arg[1], etc.
Why is it allowed ?
What can be the maximum length of such a string that is copied ?
The more I think about this thread, the more it seems to me that the
standard is quite broken on this point.

I was thinking along these lines: OK, so my program starts, and let's
say I get one command line argument, so argv[0] and argv[1] are both
pointers to strings. Perhaps argv[1] is enormously long! Now I change
it to point to something else. Alarm bells ring - I've just lost all
record of whatever argv[1] was pointing too - boom, potential memory
leak alert.

But on further reflection, even if I don't change argv[1], it's still
as good as a memory leak! Once my program has finishing doing whatever
it wants to do with its command line arguments, there's still never
any way of releasing the memory they occupy.

One practical solution would be: not only should each argv[i] be
modifiable, but in fact it should be a pointer allocated (or that
behaves as if it was allocated) by malloc. This would let the
programmer free() the memory taken up by the command line arguments
once she'd finished processing them.

Mar 16 '07 #45
Mark McIntyre wrote:
On Thu, 15 Mar 2007 23:16:18 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
Fr************@googlemail.com said:
On Mar 15, 10:59 pm, Richard Heathfield <r...@see.sig.invalid>
wrote: >>The risk to the stability of your program is potentially
high, >>
How so?
If you screw up and write too much into an argv array, you're far
more likely to trash something important than if you wrote too much
into some other array.

C&V please.

Chapter and Verse for a probability? When has the standard ever
concerned itself with that sort of thing?

Brian
Mar 16 '07 #46
On Mar 16, 1:14 am, Francine.Ne...@googlemail.com wrote:
How about this little factorial program? I think it's pretty cute.
E.g.
$ ./factorial 4
24

#include <stdio.h>
#include <stdlib.h>

struct s {
unsigned int f;
unsigned int n;

};

main(int argc, char **argv)
{
unsigned int i;
if(*argv) {
i=(unsigned int) atoi(argv[1]);
*argv=0;
argv[1]=malloc(sizeof(struct s));
((struct s*) argv[1])->n=i;
((struct s*) argv[1])->f=1;
}

if(((struct s*) argv[1])->n) {
((struct s*) argv[1])->f*=((struct s*) argv[1])->n--;
main(argc,argv);
return 0;
}
printf("%u\n",((struct s*) argv[1])->f);
free(argv[1]);
return 0;

}
Um, functionality aside, now I know what "typecasting" is =)
Seriously though, why abuse main() in such manner, unless one would
like to apply for IOCCC?
--
WYCIWYG - what you C is what you get

Mar 16 '07 #47
In article <11*********************@n59g2000hsh.googlegroups. com>
<Fr************@googlemail.comwrote:
>The more I think about this thread, the more it seems to me that the
standard is quite broken on this point.
Maybe, from a "very small memory machine" point of view anyway:
>I was thinking along these lines: OK, so my program starts, and let's
say I get one command line argument, so argv[0] and argv[1] are both
pointers to strings. Perhaps argv[1] is enormously long! Now I change
it to point to something else. Alarm bells ring - I've just lost all
record of whatever argv[1] was pointing too - boom, potential memory
leak alert.

But on further reflection, even if I don't change argv[1], it's still
as good as a memory leak! Once my program has finishing doing whatever
it wants to do with its command line arguments, there's still never
any way of releasing the memory they occupy.
Maybe not for you, but the implementation could.

Remember that your main() is called, somehow, by the implementation.
Typically this is accomplished with a bit of sneakily-written (and
usually machine-dependent in some way) code that vaguely resembles:

void __start(void) {
register struct __OS_start_info *args __sneaky("%r29");
int status;

... do some stuff with the OS-provided startup info ...
... in the process, set up argc and argv ...

__init_C_library_part_A();
__init_C_library_part_B();
...
__init_C_library_part_P();

status = main(argc, argv);

exit(status); /* __shutdown_C_library_* calls are done from exit() */
/* NOTREACHED */
}

Some of the __init calls may arrange to release the space occupied
by the argv array and strings.
>One practical solution would be: not only should each argv[i] be
modifiable, but in fact it should be a pointer allocated (or that
behaves as if it was allocated) by malloc. This would let the
programmer free() the memory taken up by the command line arguments
once she'd finished processing them.
While that might offer some advantage to a program that is running
short of memory otherwise, it would be a big change to existing
implementations, which the "OS-provided startup info" includes
storing the argv array and/or strings (and/or "environment" text
and pointers) in a stack frame that resides just "above" (or
co-incident with, depending on architecture) the frame for __start()
itself.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Mar 16 '07 #48
On Fri, 16 Mar 2007 14:19:44 +0000, in comp.lang.c , Richard
Heathfield <rj*@see.sig.invalidwrote:
>Mark McIntyre said:
>By this logic, one would never write to character arrays at all.

It's a deal. We're probably still in time for the next Standard - are
you going to write up the DR or shall I? :-)
I'm guessing in that case that there's no logic behind your aversion.
Thats fair enough - I don't like rats much, no reason why.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 16 '07 #49
On 16 Mar 2007 18:15:59 GMT, in comp.lang.c , "Default User"
<de***********@yahoo.comwrote:
>
Chapter and Verse for a probability? When has the standard ever
concerned itself with that sort of thing?
Never, of course .
My point is that if someone is is posting a prejudice ^w highly
subjective opinion, they ought to make that clear, and not try to
dress it up as anything more.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 16 '07 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
2160
by: Joe Smith | last post by:
It is nothing short of embarrassing to feel the need to ask for help on this. I can't see how I would make the main control for this. What I want is a for loop and a test condition. And while I...
0
7051
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6915
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
6993
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5353
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing,...
0
3003
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
2993
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1307
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
567
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.