Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Type of argc

161 views
Skip to first unread message

ad288

unread,
Sep 8, 2007, 7:02:07 PM9/8/07
to
Wouldn't it be more consistent to phase out the existing prefferred
proto-type for main and replace it with

int main(size_t argc, char **argv)

?

You could also consider changing the allowed return type to include long
or long long - restricting to int places an unnecessary limitation on
the range of the return code to the operating system.

Ian Collins

unread,
Sep 8, 2007, 7:36:33 PM9/8/07
to
ad288 wrote:
> Wouldn't it be more consistent to phase out the existing prefferred
> proto-type for main and replace it with
>
> int main(size_t argc, char **argv)
>
Probably, but to make the change would break too much and to add the new
from would probably cause more problems than it would solve.

>
> You could also consider changing the allowed return type to include long
> or long long - restricting to int places an unnecessary limitation on
> the range of the return code to the operating system.
>
Do your applications have more than INT_MAX return conditions?

--
Ian Collins.

Douglas A. Gwyn

unread,
Sep 9, 2007, 2:12:04 AM9/9/07
to
"ad288" <spa...@invalid.com> wrote in message
news:slrnfe6aeu....@nospam.invalid...

> Wouldn't it be more consistent to phase out the existing prefferred
> proto-type for main and replace it with
> int main(size_t argc, char **argv)

No, that would impose a sudden inconsistency with existing practice.

> You could also consider changing the allowed return type to include long
> or long long - restricting to int places an unnecessary limitation on
> the range of the return code to the operating system.

Show us a real example where the current interface types actually
cause a problem.


Richard Heathfield

unread,
Sep 9, 2007, 3:10:35 AM9/9/07
to
Douglas A. Gwyn said:

> "ad288" <spa...@invalid.com> wrote in message
> news:slrnfe6aeu....@nospam.invalid...
>> Wouldn't it be more consistent to phase out the existing prefferred
>> proto-type for main and replace it with
>> int main(size_t argc, char **argv)
>
> No, that would impose a sudden inconsistency with existing practice.

So did removing implicit int, but it improved the language nevertheless.
The whole point of size_t is to record object counts and sizes, and the
role of argc is to provide a count of the number of pointers in the
array to whose first element argv points, so size_t is absolutely the
right type for it.

Since, in our own code, most of us normally put the
pointer-to-first-element argument first, and the count afterwards
(memcpy and fgets are good standard library examples of my meaning), my
own preference for the main interface would be:

int main(char **argv, size_t argc)

but I accept that this would be, for most people, a change too far.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Keith Thompson

unread,
Sep 9, 2007, 4:07:14 AM9/9/07
to
Richard Heathfield <r...@see.sig.invalid> writes:
> Douglas A. Gwyn said:
>> "ad288" <spa...@invalid.com> wrote in message
>> news:slrnfe6aeu....@nospam.invalid...
>>> Wouldn't it be more consistent to phase out the existing prefferred
>>> proto-type for main and replace it with
>>> int main(size_t argc, char **argv)
>>
>> No, that would impose a sudden inconsistency with existing practice.
>
> So did removing implicit int, but it improved the language nevertheless.
[...]

Yes, but it was easy to write code compatible with the old and new
rules, just by not using implicit int. Changing the type of argc
would make this more difficult.

I suppose you could add the new form without removing the old one, but
I don't think it would be worth the hassle, though I'd probably use
size_t if I were designing the language from scratch.

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

ad288

unread,
Sep 9, 2007, 4:17:00 AM9/9/07
to
On 8 Sep 2007 at 23:36, Ian Collins wrote:
> ad288 wrote:
>> Wouldn't it be more consistent to phase out the existing prefferred
>> proto-type for main and replace it with
>>
>> int main(size_t argc, char **argv)
>>
> Probably, but to make the change would break too much and to add the new
> from would probably cause more problems than it would solve.

How would it break anything? The only place a change would be needed is
in the glue routine the compiler sticks in to invoke main() in the first
place - it would just need to cast whatever the OS provides for argc to
an unsigned type.

There is no reason the two styles couldn't coexist indefinitely - all it
would take is for the compiler to use different glue code depending on
whether it saw int or size_t in the signature of main().

The only problem I can imagine is for programs that make essential use
of calling main() recursively, but the work needed to port them to the
new style would probably be minimal.

>>
>> You could also consider changing the allowed return type to include long
>> or long long - restricting to int places an unnecessary limitation on
>> the range of the return code to the operating system.
>>
> Do your applications have more than INT_MAX return conditions?

What if my application performs a calculation and wants to return its
result?

Ian Collins

unread,
Sep 9, 2007, 4:43:59 AM9/9/07
to
ad288 wrote:
> On 8 Sep 2007 at 23:36, Ian Collins wrote:
>> ad288 wrote:
>>> Wouldn't it be more consistent to phase out the existing prefferred
>>> proto-type for main and replace it with
>>>
>>> int main(size_t argc, char **argv)
>>>
>> Probably, but to make the change would break too much and to add the new
>> from would probably cause more problems than it would solve.
>
> How would it break anything? The only place a change would be needed is
> in the glue routine the compiler sticks in to invoke main() in the first
> place - it would just need to cast whatever the OS provides for argc to
> an unsigned type.
>
Well for starters most existing code would fail to compile, unless both
forms were supported. If they were, then why bother with the new one?

>
>>> You could also consider changing the allowed return type to include long
>>> or long long - restricting to int places an unnecessary limitation on
>>> the range of the return code to the operating system.
>>>
>> Do your applications have more than INT_MAX return conditions?
>
> What if my application performs a calculation and wants to return its
> result?
>
Considering some environments like UNIX only use part of the range of
int for the return value (the rest indicates how the process
terminated), there would be little point on those systems.

--
Ian Collins.

André Gillibert

unread,
Sep 9, 2007, 5:34:42 AM9/9/07
to
Richard Heathfield wrote:

> Douglas A. Gwyn said:
>
>> "ad288" <spa...@invalid.com> wrote in message
>> news:slrnfe6aeu....@nospam.invalid...
>>> Wouldn't it be more consistent to phase out the existing prefferred
>>> proto-type for main and replace it with
>>> int main(size_t argc, char **argv)
>>
>> No, that would impose a sudden inconsistency with existing practice.
>
> So did removing implicit int, but it improved the language nevertheless.

That thing would only visually improve the language. It wouldn't really
improve the language.
It would have a transition cost, unless it's not adopted by programmers.
You may think, "but my proposal is backward compatible".
But ANY change in the language creates problems. Why?

Because, it makes porting programs hard.

1) New stupid programmer #1 write on platform #1:
long long main(size_t, char** argv);
2) Clever programmer #2 has to port the program to platform #2 which has a
compiler not up to date.
He has to change the declaration of main.

> The whole point of size_t is to record object counts and sizes, and the
> role of argc is to provide a count of the number of pointers in the
> array to whose first element argv points, so size_t is absolutely the
> right type for it.

Yes, it would be the right type, but to make the committee adopt a change,
you've to *prove* that it would be useful (pretty isn't useful) *right
now*, for at least *one existing* implementation, for at least *one
existing project*.

For example, for the variable return type, you could argue that you were
developing project X on platform Y using the LP64 model with 128 bits long
long, and you had to return a 128 bits MD5 to the system through the
return value, but you couldn't do it with the standard function prototype
because int was 32 bits, which is stupid because *this system* currently
*supports* 128 bits return values through a call to a system function
SysExit. Unfortunately this SysExit functions doesn't clean up correctly
your program resources so that you cannot call it: You must either call
exit() or return from main(), otherwise some system-wide resouces may leak.

In that case, we could start discussing. e.g. I could said that the
portable workaround would be to output the MD5 on stdout, which would make
the program portable to *NIX systems (you can only return one byte of
status code on those systems), and that the next revision of your program
could use a 256 bits number without changing the interface of your program.
I could also have argued that, since programs using this feature *cannot*
produce portable programs, this feature should be provided as an
extension. e.g. THIS implementation could support "long long main()" since
the C standard explicitly allow this type of extension.
5.1.2.2.3p1 "If the return type is not compatible with int, the
termination status returned to the host environment is unspecified."

For size_t, you could have argued that you were developing project X on
platform Y and you *needed* more than INT_MAX parameters, that the system
provided a size_t much larger than INT_MAX and had the capacity of passing
more than INT_MAX parameters to your program but the parameter list was
pushed as an argument to a startup function and your C implementation
couldn't report all the arguments to your main() function so that you
couldn't get all the parameters.

Then, I would have argued that for such big bunch of data, stdin is more
appropriate. And that this C implementation could provide a non-standard
way to access all the parameters (i.e. this is a QOI issue), such as
making argv a NULL-terminated string of pointers to char.

> Since, in our own code, most of us normally put the
> pointer-to-first-element argument first, and the count afterwards
> (memcpy and fgets are good standard library examples of my meaning), my
> own preference for the main interface would be:

Changing order of parameters is pointless. The transition is painful for
programmers for ZERO benefits but a ridiculously tiny consistency issue.

>
> int main(char **argv, size_t argc)
>

You seem to ignore constness issues. This is an half-baked false
improvement of main.

int main(size_t argc,char * const * argv);

Would be closer to something meaningful, but is not acceptable, as it
doesn't bring anything needed.

> but I accept that this would be, for most people, a change too far.
>

As any change in the prototype of main() would be.

--
You can contact me at <tabkanDEL...@yahoDELETETHATo.fr>

Keith Thompson

unread,
Sep 9, 2007, 3:24:28 PM9/9/07
to
ad288 <spa...@invalid.com> writes:
> Wouldn't it be more consistent to phase out the existing prefferred
> proto-type for main and replace it with
>
> int main(size_t argc, char **argv)
>
> ?

Another problem is that every main program would require a
'#include <stddef.h>' (unless you make size_t a predefined type
rather than a typedef).

Jack Klein

unread,
Sep 9, 2007, 6:53:35 PM9/9/07
to
On Sun, 09 Sep 2007 07:10:35 +0000, Richard Heathfield
<r...@see.sig.invalid> wrote in comp.std.c:

> Douglas A. Gwyn said:
>
> > "ad288" <spa...@invalid.com> wrote in message
> > news:slrnfe6aeu....@nospam.invalid...
> >> Wouldn't it be more consistent to phase out the existing prefferred
> >> proto-type for main and replace it with
> >> int main(size_t argc, char **argv)
> >
> > No, that would impose a sudden inconsistency with existing practice.
>
> So did removing implicit int, but it improved the language nevertheless.
> The whole point of size_t is to record object counts and sizes, and the
> role of argc is to provide a count of the number of pointers in the
> array to whose first element argv points, so size_t is absolutely the
> right type for it.

[snip]

Chapter and verse please. The standard defines the type size_t as the
type of the value yielded by the sizeof operator, containing the size
of an object in bytes. It is also returned by several library
functions that return sizes in bytes. And it is accepted as a
parameter by several library functions where it represents the a
memory size in bytes, and in a few cases as an additional parameter
along with a size in bytes, which will be multiplied with the size in
bytes, to yield a total size in bytes.

I see nothing in the standard even suggesting that size_t is a good
choice for counts.

While size_t can certainly be used for counts, I don't see how it
provides any benefits over any other integer type, signed or unsigned,
of sufficient range for the values it will contain.

In particular, it has no real relationship to the use of argc, because
the user program rarely cares at all about the size of the block of
memory, in bytes, taken up by the argv pointer array. Only the total
number of them.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html

Jack Klein

unread,
Sep 9, 2007, 7:02:43 PM9/9/07
to
On Sun, 9 Sep 2007 01:02:07 +0200 (CEST), ad288 <spa...@invalid.com>
wrote in comp.std.c:

> Wouldn't it be more consistent to phase out the existing prefferred
> proto-type for main and replace it with
>
> int main(size_t argc, char **argv)

What do you think that the gain would be, if any? At the moment, with
argc defined as an int, you can't portably assume that main() can
accept more than 32,765 distinct arguments.

Do you know of any platform with 16-bit ints where the only thing
preventing passing more arguments than this to a C program is the fact
that argc is a signed int?

Do you know of any platforms with 32-bit ints where the type of argc
is the only thing preventing you from passing more than 2,147,483,645
arguments?

Do you know of any 64-bit int platforms that could otherwise pass more
than 9,223,372,036,854,775,805 arguments?

> You could also consider changing the allowed return type to include long
> or long long - restricting to int places an unnecessary limitation on
> the range of the return code to the operating system.

Why not long double? Why not a struct tm? Why not... well, you get
the point.

The purpose of the return type of main, or the argument of a call to
exit(), is to pass a termination status to the environment.
Frequently, this is used in a platform-specific way to supply more
than one failure status, indicating the reason for the failure.

Since the value is not a count, negative values are just as acceptable
for implementation-defined meaning as positive ones. That means you
have a guaranteed minimum of 65,534 values distinct non-zero values
you could return. Do you really need more than that?

Richard Heathfield

unread,
Sep 9, 2007, 11:20:41 PM9/9/07
to
André Gillibert said:

> Richard Heathfield wrote:
>
>> Douglas A. Gwyn said:
>>
>>> "ad288" <spa...@invalid.com> wrote in message
>>> news:slrnfe6aeu....@nospam.invalid...
>>>> Wouldn't it be more consistent to phase out the existing prefferred
>>>> proto-type for main and replace it with
>>>> int main(size_t argc, char **argv)
>>>
>>> No, that would impose a sudden inconsistency with existing practice.
>>
>> So did removing implicit int, but it improved the language
>> nevertheless.
>
> That thing would only visually improve the language. It wouldn't
> really improve the language.

That's a contradiction. Either it's an improvement or it isn't. You seem
to think it's both. Nevertheless, I do appreciate that the game would
not be worth the candle.

<snip>


>
> Changing order of parameters is pointless.

Yes. But getting them right in the first place would not have been.
Clearly dmr was asleep that day. (No, that is not a flame. We all have
to sleep sometimes...)

>> int main(char **argv, size_t argc)
>>
>
> You seem to ignore constness issues.

But you didn't, so that's okay.

> This is an half-baked false improvement of main.

I don't agree that it's a false improvement. I am perfectly happy,
however, to agree that it is half-baked! :-)

Richard Heathfield

unread,
Sep 9, 2007, 11:24:05 PM9/9/07
to
Jack Klein said:

> On Sun, 09 Sep 2007 07:10:35 +0000, Richard Heathfield
> <r...@see.sig.invalid> wrote in comp.std.c:
>

<snip>

>> The whole point of size_t is to record object counts
>> and sizes, and the role of argc is to provide a count of the number
>> of pointers in the array to whose first element argv points, so
>> size_t is absolutely the right type for it.
>
> [snip]
>

> Chapter and verse please. [...]


>
> I see nothing in the standard even suggesting that size_t is a good
> choice for counts.

calloc, fread, and fwrite spring to mind.

>
> While size_t can certainly be used for counts, I don't see how it
> provides any benefits over any other integer type, signed or unsigned,
> of sufficient range for the values it will contain.
>
> In particular, it has no real relationship to the use of argc, because
> the user program rarely cares at all about the size of the block of
> memory, in bytes, taken up by the argv pointer array. Only the total
> number of them.

In other words, a count of objects. My point exactly.

Jack Klein

unread,
Sep 10, 2007, 1:12:32 AM9/10/07
to
On Mon, 10 Sep 2007 03:24:05 +0000, Richard Heathfield
<r...@see.sig.invalid> wrote in comp.std.c:

> Jack Klein said:
>
> > On Sun, 09 Sep 2007 07:10:35 +0000, Richard Heathfield
> > <r...@see.sig.invalid> wrote in comp.std.c:
> >
>
> <snip>
>
> >> The whole point of size_t is to record object counts
> >> and sizes, and the role of argc is to provide a count of the number
> >> of pointers in the array to whose first element argv points, so
> >> size_t is absolutely the right type for it.
> >
> > [snip]
> >
> > Chapter and verse please. [...]
> >
> > I see nothing in the standard even suggesting that size_t is a good
> > choice for counts.
>
> calloc, fread, and fwrite spring to mind.

And you snipped the part of my post where I mentioned that:

"And it is accepted as a
parameter by several library functions where it represents the a
memory size in bytes, and in a few cases as an additional parameter
along with a size in bytes, which will be multiplied with the size in
bytes, to yield a total size in bytes."

Nowhere in the standard that I can think of off-hand is the type
size_t used other than directly representing a size in bytes, or as a
value passed along with another size_t that does represent a size in
bytes.

In those cases where size_t is used to pass a count to a standard
library function, I believe it is _always_ used to multiply with
another size_t argument that is a size in bytes, to produce a product
that is a size in bytes.

So again, can you cite any of the following:

-- a library function that takes a single size_t parameter that does
not represent a size in bytes, or a function taking two size_t
parameters where neither of them is a size in bytes or the two size_t
values are not multiplied together to produce a total size in bytes?

-- any other place in the standard where size_t is used to represent
anything else other than a size in bytes?

-- any place where the standard recommends use of size_t for counting
anything other than a size in bytes?

> >
> > While size_t can certainly be used for counts, I don't see how it
> > provides any benefits over any other integer type, signed or unsigned,
> > of sufficient range for the values it will contain.
> >
> > In particular, it has no real relationship to the use of argc, because
> > the user program rarely cares at all about the size of the block of
> > memory, in bytes, taken up by the argv pointer array. Only the total
> > number of them.
>
> In other words, a count of objects. My point exactly.

If argc was the size of the argv array, in bytes, the type size_t
would be appropriate. You could then obtain the argument count by
dividing argc by sizeof *argv.

The standard mandates and includes the type size_t for one specific
purpose, namely that of holding values of sizes in bytes.

Using size_t for values representing anything other than sizes in
bytes is amateurish at best, confusing at worst. And, of course,
possibly error-prone, as code may fail when ported to a platform with
a smaller size_t that the original.

Or would you replace appropriate sized signed integer types with
ptrdiff_t?

Richard Heathfield

unread,
Sep 10, 2007, 1:35:27 AM9/10/07
to
Jack Klein said:

> On Mon, 10 Sep 2007 03:24:05 +0000, Richard Heathfield
> <r...@see.sig.invalid> wrote in comp.std.c:
>
>> Jack Klein said:
>>

<snip>


>> >
>> > I see nothing in the standard even suggesting that size_t is a good
>> > choice for counts.
>>
>> calloc, fread, and fwrite spring to mind.
>
> And you snipped

I hope you will recognise and appreciate that I snip as much as I feel
is safe from each article I post, as is common Usenet practice. I'm not
trying to change your claim, edit your words, or anything like that. It
seemed to me that the part I snipped wasn't particularly important in
relation to what I had to say. Clearly you disagree, and that probably
indicates a mind-set difference between us.

> the part of my post where I mentioned that:
>
> "And it is accepted as a
> parameter by several library functions where it represents the a
> memory size in bytes, and in a few cases as an additional parameter
> along with a size in bytes, which will be multiplied with the size in
> bytes, to yield a total size in bytes."

Yes, and that additional parameter is a size_t that represents a count
of objects. We appear to be in violent agreement.

<snip>

> Using size_t for values representing anything other than sizes in
> bytes is amateurish at best, confusing at worst.

I cannot agree that the designers of calloc, fread, and fwrite were
amateurish. Nor can I agree that their use of size_t is confusing (it
is true that I can never remember which way round the arguments go, but
I am in no doubt as to what the arguments mean!).

> And, of course,
> possibly error-prone, as code may fail when ported to a platform with
> a smaller size_t that the original.

On such a system, fewer objects are likely to be around to count, so
it's not terribly likely to matter.

> Or would you replace appropriate sized signed integer types with
> ptrdiff_t?

If they were recording the difference between two pointers, yes, why
not? And if not, then no. I'm not advocating size_t as a generic
unsigned type (and, indeed, over the weekend I pointed out why this was
a bad idea, admittedly in rec.puzzles rather than here). But I see no
harm whatsoever in using it to count objects. It is the natural type
for doing so, as the writers of calloc, fread, and fwrite clearly
agree. Oh, and qsort. And bsearch, of course.

André Gillibert

unread,
Sep 10, 2007, 6:44:14 AM9/10/07
to
Richard Heathfield wrote:


>> That thing would only visually improve the language. It wouldn't
>> really improve the language.
> That's a contradiction. Either it's an improvement or it isn't. You seem
> to think it's both. Nevertheless, I do appreciate that the game wouldnot
> be worth the candle.

Okay, I'll define my terms:
Visual improvement: Modification of the language that makes academicians
who've never written a program that's used in real life, exclaim "How
pretty it is!".

For example, the Pascal programming language (at least the original
Wirth's language) was "visually prettier" than C. It had a consistent
syntax. It had a consistent imposed procedural programming style.
Actually C was a more practical language (except for teaching), even with
all its inconsistencies.

Real improvement: Improvement that permitted to do things that weren't
possible standardly but were sometimes necessary to achieve portably, or
saved much time to many programmers for things that were difficult to do
but had to be done frequently.
Here, the term "programmers" designate developers of real-life projects
that are really used for useful things.

Even "real improvements" must be weighted against their drawbacks:
Incompatibilities they introduce.

If you want to remove all inconsistencies of the C programming language,
then, don't use C. It's hopeless. You'd rather write a new language from
scratch.

>> Changing order of parameters is pointless.
>
> Yes. But getting them right in the first place would not have been.
> Clearly dmr was asleep that day. (No, that is not a flame. We all have
> to sleep sometimes...)

No, he wasn't asleep, he was simply using different conventions at this
time.
strchr and other library functions have been written long time *after*
main(argc, argv) was invented.

He could have changed the order of parameters of main at that time, but
that would have been foolish. He wouldn't have wanted to kill his own
language.

BTW, any C programmer knows that every library follows different
conventions, and he used to manipulating various orders of parameters.

Do you know the cost of modifying the C programming language?
The committee cannot afford to modify the language if there's not a strong
rationale with at least one real life example of a need for the new
feature.

Has int ever been too small for you to store the number of arguments?
Has int ever been too small for you to store the return value?
Do the lack of constness made loose thousands of dollars in debugging to
thousands of companies?

Statistics are welcome.

André Gillibert

unread,
Sep 10, 2007, 6:51:41 AM9/10/07
to
Jack Klein wrote:

>
> -- a library function that takes a single size_t parameter that does
> not represent a size in bytes, or a function taking two size_t
> parameters where neither of them is a size in bytes or the two size_t
> values are not multiplied together to produce a total size in bytes?

wcsncpy
wmemcpy
wmemmove
wsncat

And other wide-string functions.

André Gillibert

unread,
Sep 10, 2007, 7:03:21 AM9/10/07
to
Jack Klein wrote:

>
> Do you know of any platforms with 32-bit ints where the type of argc
> is the only thing preventing you from passing more than 2,147,483,645
> arguments?

With the LP64 and LLP64 model, that might become the case in future.

Right now, I don't think this limit is a practical problem. OS have often
lower limits.
(I can pass more than 50 megabytes of argument data with Windows 98 SE,
but I cannot pass 2,147,483,646 arguments).

Richard Tobin

unread,
Sep 10, 2007, 7:01:11 AM9/10/07
to
In article <bpj9e3lpjt7ct8cra...@4ax.com>,
Jack Klein <jack...@spamcop.net> wrote:

>So again, can you cite any of the following:
>
>-- a library function that takes a single size_t parameter that does
>not represent a size in bytes

swprintf() takes a size_t that is a number of wchar_t.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.

Richard Heathfield

unread,
Sep 10, 2007, 9:24:23 AM9/10/07
to
André Gillibert said:

> Richard Heathfield wrote:
>

<snip>

>> Nevertheless, I do appreciate that the game

>> would not be worth the candle.

I have retained the above quote in case you didn't notice it last time.

<snip>

>>> Changing order of parameters is pointless.
>>
>> Yes. But getting them right in the first place would not have been.
>> Clearly dmr was asleep that day. (No, that is not a flame. We all
>> have to sleep sometimes...)
>
> No, he wasn't asleep, he was simply using different conventions at
> this time.

That's a fair point...

<snip>

> He could have changed the order of parameters of main at that time,

...but this isn't. The point I was making was that, if he'd put them the
other way around ***in the first place***, there would have been no
reason to switch them. (No, I am not advocating that they should be
switched. I live in the real world too!)

> Do you know the cost of modifying the C programming language?

I am not advocating a change. I am expressing a "woulda been nice if",
that's all.

<snip>

André Gillibert

unread,
Sep 10, 2007, 1:23:53 PM9/10/07
to
Richard Heathfield wrote:

> André Gillibert said:
>
>> Richard Heathfield wrote:
>>> Nevertheless, I do appreciate that the game
>>> would not be worth the candle.
>
> I have retained the above quote in case you didn't notice it last time.
>

Ok.

> The point I was making was that, if he'd put them the
> other way around ***in the first place***, there would have been no
> reason to switch them.

Right.

> I am not advocating a change. I am expressing a "woulda been nice if",
> that's all.
>

Yes.
In the same idea of "would have been nice if", it would have been prettier
if argv either was totally modifiable (i.e. that char** argv had the
contract that the lack of constness qualifier seems to indicate) or
unmodifiable (i.e. that argv be of type char const * const *).

Jack Klein

unread,
Sep 10, 2007, 11:48:23 PM9/10/07
to
On Mon, 10 Sep 2007 12:51:41 +0200, "André Gillibert"
<tabkanDEL...@yahodeletethato.fr> wrote in comp.std.c:

> Jack Klein wrote:
>
> >
> > -- a library function that takes a single size_t parameter that does
> > not represent a size in bytes, or a function taking two size_t
> > parameters where neither of them is a size in bytes or the two size_t
> > values are not multiplied together to produce a total size in bytes?
>
> wcsncpy
> wmemcpy
> wmemmove
> wsncat
>
> And other wide-string functions.

Obviously, I am not making my point clearly enough for either Richard
or you to see it, so I am going to give up after this.

If I did make it clear enough, you'd see that these functions actually
reinforce the point I was trying to make.

There are two ways to look at these and similar functions:

The size_t parameter does represent a size in bytes, indeed directly
if sizeof(wchar_t) is 1.

Or the size_t parameter can be looked at as analogous to the calloc,
fread, fwrite case, where it is a count of objects to be multiplied by
the size_t value representing the size of the object, in bytes, to
yield the total memory size, in bytes.

In the case of wide string functions, one needs to supply "size_t
nmemb" value, the "size_t size" second value is implicit, as for any
given invocation of a translator it is sizeof(wchar_t), a compile-time
constant expression.

But, as I said, I give up.

Richard Heathfield

unread,
Sep 11, 2007, 12:29:14 AM9/11/07
to
Jack Klein said:

<snip>



> Obviously, I am not making my point clearly enough for either Richard
> or you to see it, so I am going to give up after this.

Sorry, Jack, but it's true - although I can understand why *you* might
choose not to use size_t for object counts, I can't understand why you
think it amateurish (at best!) for others so to do. As you suggest, it
may be best simply to agree to differ.

<snip>

André Gillibert

unread,
Sep 11, 2007, 5:37:01 AM9/11/07
to
Jack Klein wrote:


> Obviously, I am not making my point clearly enough for either Richard
> or you to see it, so I am going to give up after this.
>
> If I did make it clear enough, you'd see that these functions actually
> reinforce the point I was trying to make.
>

Unfortunately, your question about finding a function was put in a pretty
explicit wording, letting no room for any subjective notion of parameter
which made me think that you really thought that size_t counts are ok if
and only if they're together with an *explicit* object size.

> There are two ways to look at these and similar functions:
>
> The size_t parameter does represent a size in bytes, indeed directly
> if sizeof(wchar_t) is 1.

As size_t would represent a size in bytes in main if sizeof(char*) is 1.

> Or the size_t parameter can be looked at as analogous to the calloc,
> fread, fwrite case, where it is a count of objects to be multiplied by
> the size_t value representing the size of the object, in bytes, to
> yield the total memory size, in bytes.

Same thing for the alternative prototype of main.

int main(size_t argc, char** argv);

argc is the count of objects to be multiplied by the size_t value
representing the size of the object (char*).

size_t is either for sizes of objects (as you said), or for counts of
objects (as you said too) in a context where an explicit (as you said in
several posts) *or implicit* (as you said in your last post) size of
object is defined so that the size of an array is obtained by multiplying
the count by the size of objects (so I think you find it ok for arrays but
not ok for linked lists).

How is main(size_t, char**) different?

>
> In the case of wide string functions, one needs to supply "size_t
> nmemb" value, the "size_t size" second value is implicit, as for any
> given invocation of a translator it is sizeof(wchar_t), a compile-time
> constant expression.
>

sizeof(char*) is implicit and a compile-time constant expression too.


Okay, I think I'll have to quote older posts:

> While size_t can certainly be used for counts, I don't see how it
> provides any benefits over any other integer type, signed or unsigned,
> of sufficient range for the values it will contain.

It provides at least a benefit over intmax_t: It's likely to have a
smaller size and arithmetic on it be faster.
All other integer types, except intmax_t, may create cases where the limit
imposed to the number of arguments is smaller than the limit provided by
the system.
With size_t, this cannot be the case, because, the size of the array of
char* must be smaller or equal to SIZE_MAX (ignoring perverse
implementations where objects can be larger than SIZE_MAX bytes).
Since sizeof(char*)>=1, the count of char* elements in the array is
smaller or equal to SIZE_MAX/sizeof(char*) <= SIZE_MAX.
Thus, size_t and intmax_t are the only types that guarantee an optimial
benefit from system's capacities, without any major change to the
interface of the C programming language.

One could think that a 64 bits system with terabytes of RAM, and where
hundred of thousands of command line arguments are common, but with 16
bits int (in the spirit of Microsoft models).

I don't claim such a system exists, and that's why I don't advocate any
change in the language.


> In particular, it has no real relationship to the use of argc, because
> the user program rarely cares at all about the size of the block of
> memory, in bytes, taken up by the argv pointer array.

Not so rarely.
IIRC, once, I wrote something that malloc'ed a second array of char* and
memcpy'ed the old one in it:

memcpy(margv, argv, ((size_t)argc)*sizeof(char*)); /* Now, margv is a
pointer to a modifiable array of char* */

That was because I needed to temporarily modify some elements of the array.

Charlie Gordon

unread,
Sep 11, 2007, 6:19:46 AM9/11/07
to
"André Gillibert" <tabkanDEL...@yahodeletethato.fr> a écrit dans le
message de news: op.tyhgzzdw7pu1mk@andre...
> How is main(size_t argc, char **argv) different?

This discussion is quite useless IMHO, and I don't mean to argue for size_t
argc, but is this particular example, argc is not the count of elements in
the argv array, argv need one more element for the final NULL.

As such, argc is the "length" of argv, not its "size", in an analogy with
strings where strlen("foo") != sizeof("foo").
We are all quite used to this notion, but it is counter-intuitive for most
newbies, and countless self-described proficient programmers still stumble
upon it when mallocing strlen(s) bytes to save a copy of string s.

Can we stop this thread now ?

--
Chqrlie.


ad288

unread,
Sep 11, 2007, 7:31:44 AM9/11/07
to
On 11 Sep 2007 at 10:19, Charlie Gordon wrote:
> This discussion is quite useless IMHO, and I don't mean to argue for size_t
> argc, but is this particular example, argc is not the count of elements in
> the argv array, argv need one more element for the final NULL.
>
> As such, argc is the "length" of argv, not its "size", in an analogy with
> strings where strlen("foo") != sizeof("foo").
> We are all quite used to this notion, but it is counter-intuitive for most
> newbies, and countless self-described proficient programmers still stumble
> upon it when mallocing strlen(s) bytes to save a copy of string s.

But strlen() returns a size_t, so I don't see how this is supposed to
support your argument that argc shouldn't be a size_t.

Message has been deleted
0 new messages