Here's the scoop. Apologies for inaccuracies or omissions, this is filtered
by my jet-lagged memory and my personal interests. For instance, I really
can't tell you much about the details of the ongoing floating point work.
Salient points:
1. old-style decls and defns have not been removed, but remain
an obsolescent feature. The rationale is that it hasn't been long
enough since there were widely used compilers that didn't support
new-style functions.
2. strsep and strdup are not being added. strsep() is out because
not enough people wanted it to vote it in; strdup() lost on the
grounds that it would be the *ONLY* function other than *alloc()
in the entire library whose return could be sanely passed to free(),
and this is surprising.
3. We have mixing of declarations and code; you can declare a
variable in the first (no-longer-expression) of a for loop, and its
scope is the loop. It does *NOT* exist after the end of the loop. In
general, objects can be declared at any point.
4. We have inline functions. Many obscure technical points have
become fogged by the mists of Northwest Airlines and painfully small
chairs, but we do allow for, without requiring, the magic of "extern
inline". Externally visible inline functions may not declare static
variables. You can declare a local inline version of a function
(perhaps in this module you know that the function is more trivial
than it is elsewhere, so you want a faster version), but in such
cases, it will be unspecified which version you get. (This avoids a
very nasty morass of attempts to rule whether, say { return a + b; }
and { return a - b; } are "compatible" function definitions, in a
module where you know b is always 0. You will probably get the local
one from most compilers.)
5. We have variable length arrays. The expressions may have side
effects, but it is unspecified whether and when they are produced.
Do not put side effects you care about in the size expr of a VLA.
6. We have compound literals. i.e.,
asctime(&((struct tm) { .tm_year = 97 }));
Yes, you can take their addresses. They are writeable; they behave
like automatic variables.
7. We have (as you may have guessed) designated initializers.
8. It is now a constraint violation for a return statement in a
non-void function to not have an expression. YAY!!!!!
9. There are many, many, many small cleanups. I believe we did
accept the wording which guarantees that you may pass &va to
a function which then modifies *arg, and expect a va_list to survive
the process "as expected" (i.e., arguments consumed by the child in
this case are really consumed from the va_list, and everything stays
coherent.) This is *NOT* changing what happens if you pass the
va_list to a child function; it is changing what happens with an & on
va_list, which is different. (Actually, it isn't changing it, it's
clarifying the existing meaning, IMHO.)
10. Tom Plum is doing wording to define explicitly the behavior of
printf("%n%n", &foo, &foo);.
11. There is now room in the type system for additional
implementation-defined integer types. (And, as a convenient
corollary, <inttypes.h> now reserves int*_t and uint*_t. That's
my paper! This way, we steal your namespace once and all at
once, not by bits and pieces.)
12. We have a true boolean type such that any value which does not
compare equal to zero becomes "true" and values which compare equal to
zero become "false".
The last one is controversial. We had a proposal which made bool a typedef
for some other type, with the obvious limitation that
bool a, b;
a = isalpha('a');
b = isxdigit('a');
assert(a == b);
might not work. Then we had a new proposal which would make it work, by
making the conversion enforce the true/false modes of bool... but it didn't
adequately support bool bitfields, which are important to some people.
Wording was attempted, and was not quite correct...
At this point, you have to understand that we're pushing the envelope for
how long we can spend on this before we emit our CD, which is expected to be
a fairly final standard. The question is...
Is it better to have a *concept* that has had the widespread and solid support
of the committee for more than a year, with known bugs in the wording, or a
concept that (no offense meant, Tom Plum did a beautiful job of sketching it
out) really isn't what we want, but has no known bugs in the wording?
I ended up on the "good concept, bad wording" side. I feel that, if there
are bugs in the wording we present, we have a good chance of fixing them
during our comment period, but there's really no chance of correcting a
basically different feature during that period. I have volunteered to try to
help with the review group that'll be cleaning up these words; depending, I
may be able to get some copies of some of this text posted here, although a
lot of the changes are relative to a draft that we are not yet able to make
public.
It currently looks to me as though public availability will be
sometime around September; I may be incorrect.
Lots of other little cleanup occurred.
Overall, I think we win big. I think C9X is a good, mature language. I wish
I had a compiler for it; a lot of very ugly code I currently maintain would be
small, simple, and effective were it written in C9X.
Oh, one other note: We have formally made it clear that backslash-newlines
DO NOT NEST. The famous code example
---
a\\
b
---
Is really equivalent to
---
a\
b
---
which is not syntactically valid.
I don't care much either way on that decision, but I like having an answer.
This article may be reproduced in its entirety with attributions. Please
do *NOT* quote pieces of it, outside the context of followups to it, without
discussing it with me. I'm trying to control the rampant spread of rumors
about C9X.
-s
--
Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
I am not actually st...@quantcom.com but junk mail is accepted there.
The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.
<A lot of people are doubtless curious as to what happened at the C9X meeting.
Well, yes...
<Salient points: 1. old-style decls and defns have not been removed, but
<remain an obsolescent feature.
Pity. Compilers could have become simpler. Next time?
<2. strsep and strdup are not being added. strsep() is out because not enough
<people wanted it to vote it in; strdup() lost on the grounds that it would be
<the *ONLY* function other than *alloc() in the entire library whose return
<could be sanely passed to free(), and this is surprising.
Then why not stralloc()?! Yes, strdup is existing usage, but now we all have
to continue to write our own strdup, knowing *full well* the runtime contains
the same thing almost everywhere we go.
<3. We have mixing of declarations and code; you can declare a variable in the
<first (no-longer-expression) of a for loop, and its scope is the loop. It
<does *NOT* exist after the end of the loop. In general, objects can be
<declared at any point.
Thank you.
<4. We have inline functions.
Thank you.
<5. We have variable length arrays. The expressions may have side effects, but
<it is unspecified whether and when they are produced. Do not put side effects
<you care about in the size expr of a VLA.
Thank you! Can you give an example? What happens to 0 and negative values?
Is this defined for automatic variables only?
<6. We have compound literals. i.e., asctime(&((struct tm) { .tm_year = 97
<})); Yes, you can take their addresses. They are writeable; they behave like
<automatic variables.
*Blink* I'll wait for the comment period. I'd love to see the full description
of this.
<7. We have (as you may have guessed) designated initializers.
Thank you. Bwah hahaha! I've wanted this for years!
<8. It is now a constraint violation for a return statement in a n The last
<one is controversial.
PLEASE REPOST WITH THE MISSING BIT. Something got lost somewhere.
--
Well, it got here intact. The error is probably in your newsreader,
but may be in an intermediate server.
Nick Maclaren,
University of Cambridge Computer Laboratory,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679
That's not a "Thank you," that's an, "Oh my god, *WHY*?!?!"
It doesn't make code more readable; it doesn't make it more maintainable;
and it adds very little to compiler simplicity.
It's one of the things I hate seeing in C++, and now I'm going see that crap
in C.
Gosh, thanks.
I know. I waffled on this, however, in the end, I stand by the theory that
*no* function in the standard library should return a free'able pointer,
unless it's one of the memory management functions. Why?
Let's say you want to write a malloc debugger. Let's further say you already
have. Will it still work if there are new library routines silently calling
the library's malloc and not using your wrapper functions? Oops.
><5. We have variable length arrays. The expressions may have side effects, but
><it is unspecified whether and when they are produced. Do not put side effects
><you care about in the size expr of a VLA.
>Thank you! Can you give an example? What happens to 0 and negative values?
>Is this defined for automatic variables only?
Auto only, yes. Not allowed as members of structs or unions, I believe. I
*think* negative and 0 sizes are undefined behavior, but I haven't got a
viable draft handy. Examples:
void foo(int x) {
int a[x]; /* a has x members now */
}
tree *maketree(int nitems, item items[]) {
int stack[(int) (log(nitems) * 2) + 5];
...
}
Note that in the 2nd example, you really do get log(nitems), even though we
don't guarantee the ordering or frequency of side effects.
Do *NOT* get funky and try something like
int a[sprintf(b, fmt, ...)];
><6. We have compound literals. i.e., asctime(&((struct tm) { .tm_year = 97
><})); Yes, you can take their addresses. They are writeable; they behave like
><automatic variables.
>*Blink* I'll wait for the comment period. I'd love to see the full description
>of this.
So would I; it's recent enough the draft doesn't do it, although I suppose
I could probably quote large portions of the proposal.
><8. It is now a constraint violation for a return statement in a n The last
><one is controversial.
>PLEASE REPOST WITH THE MISSING BIT. Something got lost somewhere.
Eek!
I am informed reliably that this really did make it to at least one other
person complete, but, since you my special friend, I make you special deal.
---Repost of previous article.
<>Then why not stralloc()?!
<I know. I waffled on this, however, in the end, I stand by the theory that
<*no* function in the standard library should return a free'able pointer,
<unless it's one of the memory management functions. Why?
So what's wrong with adding char *stralloc(char *c)? Call it a memory
management function. Everyone's happy.
<Auto only, yes. Not allowed as members of structs or unions, I believe. I
<*think* negative and 0 sizes are undefined behavior, but I haven't got a
<viable draft handy. Examples: void foo(int x) { int a[x]; /* a has x members now */ }
*Blink* And... sizeof(a) ??? For this to work properly, the compiler has to plant
some interesting stuff in a hidden place... stuff that would help diagnose
array bounds errors...
Sorry. Momentary lapse of reason. This is still C. :)
<>PLEASE REPOST WITH THE MISSING BIT. Something got lost somewhere.
<I am informed reliably that this really did make it to at least one other
<person complete, but, since you my special friend, I make you special deal.
Thanks. The fault is on my system. My mail app doesn't like lines of
over 1024 characters, and it is sadistic about it; something I've just
discovered. Heh heh.
--
Now if you'd just raise the printf directive limit from 509 to 2G...
<aol>
Seconded.
</aol>
John
--
John Winters. Wallingford, Oxon, England.
Just classify `strdup()' as a memory management rather than
a string function; problem solved. Both sets of routines are
conveniently declared by the same header file. :-} Add memdup()
too if you really need to feel better about this.
Not adding strdup() because it's too trivial to bother with
would be better reasoning....
: Let's say you want to write a malloc debugger. Let's further say you already
: have. Will it still work if there are new library routines silently calling
: the library's malloc and not using your wrapper functions? Oops.
Another non-issue, since nothing prevents the library from
using--or mis-using--the other memory management functions directly,
and wrappers cannot intercept such calls. Code you wrote for the
current standard will have to be updated if you intend to use it
with the new features of the future standard anyway.
I agree with the earlier comment that allowing declations to
be intermixed with statements is a dreadful feature. C++ should
never have added it and C should definitely not start replicating it.
Pat Rankin, ran...@eql.caltech.edu
But the memory management functions should never know about the
magic of data types and things.
><Auto only, yes. Not allowed as members of structs or unions, I believe. I
><*think* negative and 0 sizes are undefined behavior, but I haven't got a
><viable draft handy. Examples: void foo(int x) { int a[x]; /* a
><has x members now */ }
>*Blink* And... sizeof(a) ???
Yup.
Note that sizeof() on a variably-modified type *is not constant*, and
may evaluate its argument!! Be careful!
>For this to work properly, the compiler has to
>plant
>some interesting stuff in a hidden place... stuff that would help diagnose
>array bounds errors...
Yes.
>Thanks. The fault is on my system. My mail app doesn't like lines of
>over 1024 characters, and it is sadistic about it; something I've just
>discovered. Heh heh.
Were there lines of over 1024 characters? If so, there has been another
problem somewhere out there.
>Now if you'd just raise the printf directive limit from 509 to 2G...
I think it's now 4095, but I'm not sure.
Because it's a holy war issue. Some people like it, some don't.
>It doesn't make code more readable; it doesn't make it more maintainable;
>and it adds very little to compiler simplicity.
I disagree on the first two points. Well, I agree, but only on pedantry.
No, it doesn't make code more readable. Not always. But it *CAN*.
Why on earth should I declare a variable 'i' 30 lines up from a for loop
when it will be used only one one or two lines of a largish function?
Why should I declare variables far from their use?
It's very spirit-of-C. It can hurt you badly, or help you a lot.
I am afraid that you have missed the point. It can lead to significant
increases in efficiency on many systems, and is one of the reasons that
Fortran loops produce so much better code than C ones.
The circumstance where it matters is on vector, pseudo-vector and some
RISC systems where eliminating the loop variable entirely can remove a
serialisation from within the loop. And this can be done (in general)
only if the loop variable does not carry its value to outside the loop.
<>So what's wrong with adding char *stralloc(char *c)? Call it a memory
<>management function. Everyone's happy.
<But the memory management functions should never know about the
<magic of data types and things.
stralloc() wouldn't! It's just a strlen, an increment, a malloc, and
a memcpy. In other words, it's a malloc. No special information needed;
I only suggested it return char* so it wouldn't have to be cast when
I use it in C++.
It's not a big deal; it isn't as if I haven't written it, under the
name of istrdup, everywhere I've been. It's just such a bloody common
operation, and implemented efficiently by so many implementations
already *anyway*, that I hate seeing it miss standardization.
<>Now if you'd just raise the printf directive limit from 509 to 2G...
<I think it's now 4095, but I'm not sure.
*Snicker* So it is now safe to admit which implementation was defended
by the original choice of 509?
<>><3. We have mixing of declarations and code; you can declare a variable in the
<>><first (no-longer-expression) of a for loop, and its scope is the loop. It
<>><does *NOT* exist after the end of the loop. In general, objects can be
<>><declared at any point.
<>>Thank you.
<>That's not a "Thank you," that's an, "Oh my god, *WHY*?!?!" ...
<>It's one of the things I hate seeing in C++, and now I'm going see that crap
<>in C.
<<aol>
<Seconded.
<</aol>
I'll vote the other way. I *like* having the variable declared,
and inited, near the point of use. Simplifies automatic code
generation, too.
I don't follow your argument at all. Any half-way decent compiler can
determine without syntactic help that the value of the loop variable is
not used outside the loop, and do exactly the same optimisations as if
the variable belonged to the loop.
,
Eamonn http://www.gr.opengroup.org/~emcmanus
"Frustra fit per plura quod potest fieri per pauciora" -- Occam
I have to side with those dismayed by this change. The C++ syntax is
really ugly. As I understand it, I can write:
for (int i = 0; i < N; i++) ...
or
for (int i = 0, j = N; i < j; i++, j--) ...
but not
for (int i = 0; long j = N; 1<<i < j; i++, j >>= 1) ...
It seems as horribly wrong to allow declarations here as it did to
allow them in function declarations, but without the excuse of the
enormous utility of prototypes. Particularly if you can now throw in a
declaration of i just before the loop, it's hard to see that the
marginal convenience of a variable whose scope is exactly the for()
justifies this enormous syntactic wart. Can definitions be inserted
into if() or while()? If not why not?
> 5. We have variable length arrays. The expressions may have side
> effects, but it is unspecified whether and when they are produced.
> Do not put side effects you care about in the size expr of a VLA.
I'm interested in more details about this. Presumably committee
members were familiar with Dennis Ritchie's 1989 paper "Variable-Size
Arrays in C". A few questions and comments inspired by that paper:
- Are variable-length array parameters allowed?
- If so, what is their syntax? Is it something like gcc's:
int f(int n, int a[n]) {...}
What does a prototype for such a function look like? Can you
define a function where the array size expression uses
parameters that appear after the array parameter?
- The proposal clearly violates the "spirit of C" in that it calls
for complex run-time support. In essence the committee has
mandated alloca(), and implementations will have to deal with
all the tricky problems that implies, particularly in the
presence of longjmp(). Ritchie gives this example:
for (i = 1; i < 1000; i++) {
int a[i];
if (done())
continue;
}
and notes that the compiler must notice the `continue' so as to
release the storage of a[], and that the implementation must be
able to deal with the case where done() calls longjmp(). Both
of these mean that a minimal C compiler suddenly becomes a much
more complex beast.
If you're going to write in AOL mode, you should use the correct syntax.
>
> Seconded.
You misspelled "Me too!".
>
> </aol>
>
Hope this helps...
--
Chris Volpe Phone: (518) 387-7766
GE Corporate R&D Fax: (518) 387-6560
PO Box 8 Email: "volpecr" AT "crd.ge.com"
Schenectady, NY 12301 Web: http://www.crd.ge.com/~volpecr
.
.
At least some parts of C know about char * strings already. Isn't that's
why there are string literals?
OK, it doesn't belong in <string.h>, it belongs in <stdlib.h> with the
rest of the memory allocation stuff. BUT IT IS STILL NEEDED!
Ack! I understand the "not a constant" part, but why evaluate its
argument? Does the following invoke undefined behavior?
int foo(int x)
{
void (*p)[x]; /* declare pointer to array of length x */
int psize = sizeof(*p);
return psize;
}
Note that if sizeof can evaluate its argument in the above, since the
"*p" argument has type "array of variable length", then the evaluation
of "*p" invokes undefined behavior, since p has not been initialized.
Why must this be the case? I can understand if the compiler needs to
generate code to evaluate "x" in response to the sizeof operator, but it
shouldn't have to evaluate the operand of sizeof itself.
It can make code more readable and maintainable, if it is used properly.
It
can also do the reverse. Any language feature can be abused.
It adds very little to compiler complexity also. Over all, it comes
down
to personal preference and style. I prefer to set my own style rather
than
have it dictated to me.
>
> I am afraid that you have missed the point. It can lead to significant
> increases in efficiency on many systems, and is one of the reasons that
> Fortran loops produce so much better code than C ones.
You can get that effect now by putting the loop in its own block and
declaring the index varible in that block. It's a wash in this regard.
From another branch of this thread about declarations in loops:
Yes, the syntax is a bit clumsy. There are cases where adding a scope
block is the only practical way to achieve the desired effect. BUT
experience with C++ has shown that this is a useful syntactic short
cut.
While we will all have to learn this new syntax in order to read other
peoples code, no one is being forced to USE the new syntax. Since it
is already in C++, anybody who has been trying to keep up understands
the syntax already. Also, it is one less rule for the newbies to trip
over.
>In article <207b3.sm...@ziplink.net>,
>Scott Mayo <sm...@ziplink.net> wrote:
>
>>Thanks. The fault is on my system. My mail app doesn't like lines of
>>over 1024 characters, and it is sadistic about it; something I've just
>>discovered. Heh heh.
>
>Were there lines of over 1024 characters?
No, there weren't (at least, not on my news server). All the lines were
decently sized. Scott's mail client must be really difficult to satisfy :-)
Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - PPE, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
>Peter Seebach wrote:
>>
>> Note that sizeof() on a variably-modified type *is not constant*, and
>> may evaluate its argument!! Be careful!
>
>Ack! I understand the "not a constant" part, but why evaluate its
>argument?
Because the size of the array might be stored in front of the first
element of the array, just like many malloc implementations do.
>Does the following invoke undefined behavior?
>
>int foo(int x)
>{
> void (*p)[x]; /* declare pointer to array of length x */
x = 0;
> int psize = sizeof(*p);
> return psize;
>}
>
>Note that if sizeof can evaluate its argument in the above, since the
>"*p" argument has type "array of variable length", then the evaluation
>of "*p" invokes undefined behavior, since p has not been initialized.
>
>Why must this be the case? I can understand if the compiler needs to
>generate code to evaluate "x" in response to the sizeof operator, but it
>shouldn't have to evaluate the operand of sizeof itself.
Consider my change to your example and you'll see why it doesn't make any
sense for the compiler to generate code to evaluate "x" in response to the
sizeof operator. The size of the array must be somehow associated with
the address of the array and to obtain that address the argument of the
sizeof operator might need to be evaluated (in your example it *needs* to
be evaluated).
Sounds like a compiler option is in order here. I know I would throw it
more times than I would like to admit!
I would bet that if a secret ballot was taken, *everyone* would be
suprised how many closet Pascal programmers we have lurking.
[I'm only slightly kidding - randy]
--
Randy Stegbauer
email: Randy.S...@sdrc.com phone: 513-576-7610
-- Who says Unix users aren't creative?
echo "[q]sa[ln0=aln85%Pln85/snlbx]sb17400184584968385552336snlbx"|dc
-- Who did I steal this sig from?
>>It doesn't make code more readable; it doesn't make it more maintainable;
>>and it adds very little to compiler simplicity.
>
>I am afraid that you have missed the point. It can lead to significant
>increases in efficiency on many systems, and is one of the reasons that
>Fortran loops produce so much better code than C ones.
>
>The circumstance where it matters is on vector, pseudo-vector and some
>RISC systems where eliminating the loop variable entirely can remove a
>serialisation from within the loop. And this can be done (in general)
>only if the loop variable does not carry its value to outside the loop.
I agree that it may make it an easier job for the compiler if the
scope of the loop variable is only the loop, but can't the same thing
be done with an analysis of the code? Does the compiler need to worry
about reference through a pointer if no pointer assignment is made to
the variable?
Any time I want to limit the scope of a variable in C I can begin a
new block.
Thad
>int foo(int x)
>{
> void (*p)[x]; /* declare pointer to array of length x */
> int psize = sizeof(*p);
> return psize;
>}
I am unsure.
Think about this one:
int *ip = 0;
(void) sizeof(int [*ip]);
Undefined behavior. Obviously, you can't implement sizeof on a VLA type
without evaluating *something*.
>Note that if sizeof can evaluate its argument in the above, since the
>"*p" argument has type "array of variable length", then the evaluation
>of "*p" invokes undefined behavior, since p has not been initialized.
I don't think it does in that case, because 'pointer to array' is
probably of known size.
>Why must this be the case? I can understand if the compiler needs to
>generate code to evaluate "x" in response to the sizeof operator, but it
>shouldn't have to evaluate the operand of sizeof itself.
I'm not sure it does in the expression case; it can need to in the type case.
--
Peter Curran pcu...@xacm.org
(remove x for actual address)
Indeed.
>>It doesn't make code more readable; it doesn't make it more maintainable;
>>and it adds very little to compiler simplicity.
>I disagree on the first two points. Well, I agree, but only on pedantry.
>No, it doesn't make code more readable. Not always. But it *CAN*.
Indeed; very much so. If you don't like the feature, don't use it. If
you do, you now can.
>Why on earth should I declare a variable 'i' 30 lines up from a for loop
>when it will be used only one one or two lines of a largish function?
>Why should I declare variables far from their use?
And, much more to the point, why should I declare variables before I
know what value they'll take.
Given this feature, you need never be bitten by an uninitialize variable
again. Believe me, that's a *big* win. Plus, as a bonus, you no longer
need keep around a pool of loop variables that risk getting misused;
each loop variable is available where it's needed, *only* where it's
needed.
--
Clive D.W. Feather | Director of Software Development | Home email:
Tel: +44 181 371 1138 | Demon Internet Ltd. | <cl...@davros.org>
Fax: +44 181 371 1037 | <cl...@demon.net> |
Written on my laptop; please observe the Reply-To address |
The feeling was that it is too soon; compilers allowing prototypes have
only become common in the last few years, and there is a lot of legacy
code.
By contrast, implicit int has been completely removed (all declarations
require at least one type specifier) because you've been able to write
such code from day one.
><2. strsep and strdup are not being added. strsep() is out because not enough
><people wanted it to vote it in; strdup() lost on the grounds that it would be
><the *ONLY* function other than *alloc() in the entire library whose return
><could be sanely passed to free(), and this is surprising.
Not quite. In both cases an expressed view was that these functions
don't *need* to be in the Standard; they are easy enough to write or
provide in a user library. [If we'd been starting from scratch, much of
the library would have been excluded for basically this reason.]
By contrast, the v*scanf() family was voted in, because these are almost
impossible to write without access to the system library's internals.
>Then why not stralloc()?! Yes, strdup is existing usage, but now we all have
>to continue to write our own strdup, knowing *full well* the runtime contains
>the same thing almost everywhere we go.
The name wasn't the point. Calling it stralloc() doesn't affect the
arguments - the present interface between the heap and the rest of the
world consists of malloc(), realloc(), calloc(), and free(). Various
arguments were made for retaining this simplicity, and they won. A
secondary point was that strdup() on its own is insufficient - why not
strndup(), stralloccat(), wcsdup(), memdup(), and so on ?
><3. We have mixing of declarations and code;
>Thank you.
You're welcome (that was my proposal).
><6. We have compound literals. i.e., asctime(&((struct tm) { .tm_year = 97
><})); Yes, you can take their addresses. They are writeable; they behave like
><automatic variables.
>*Blink* I'll wait for the comment period. I'd love to see the full description
>of this.
It's on one of the public web sites. Try <ftp://ftp.dmk.com/DMK>, I
think.
Basically:
(struct <tag>) { <list of initializers> }
is an expression that is equivalent to the name of a local variable
which is assigned the initializers at that point in the execution of the
code. Modulo wording errors, the scope of the variable is the current
function call, and the assignment happens *each* time you reach the
compound literal. It's a true object - you can take its address, for
example.
Generally, "inline" tells the compiler to look at optimizing this
function (a bit like "register"). It has no formal effect on static
functions.
For external functions, one translation unit must define the function in
the normal way; either the definition or a preceeding declaration must
omit the inline keyword. This is the primary definition.
Any other translation unit may provide a body for the function, but in
this case *all* declarations in that TU must use the inline keyword. It
is unspecified, in that TU, whether calls invoke the local body or the
primary one. The semantics are exactly as if you replace the definition
of "f" with "__local_f" and all calls to "f" with:
(__random_boolean () ? f : __local_f)(arguments)
Note that uses other than calls refer to the primary definition
(including complex calls like "(*&*&f)(arguments)").
> 9. There are many, many, many small cleanups. I believe we did
> accept the wording which guarantees that you may pass &va to
> a function which then modifies *arg, and expect a va_list to survive
> the process "as expected" (i.e., arguments consumed by the child in
> this case are really consumed from the va_list, and everything stays
> coherent.)
No, we ran out of time. It's still in the queue.
> 10. Tom Plum is doing wording to define explicitly the behavior of
> printf("%n%n", &foo, &foo);.
And, more to the point, multiple uses of the same object in scanf().
<>Were there lines of over 1024 characters?
<No, there weren't (at least, not on my news server). All the lines were
<decently sized. Scott's mail client must be really difficult to satisfy :-)
Scott's mail system is, er, somewhat homebrew and incomplete, and has a number
of limitations I mean to get around to fixing. Very soon now.
There are three problems with doing it solely by analysis (i.e. with no
help from the syntax): it isn't always possible, it is much more prone
to error, and the information is not always available until a later
stage of compilation. And, yes, the compiler DOES need to worry even
if no direct use is made of the variable.
>Any time I want to limit the scope of a variable in C I can begin a
>new block.
Yes, someone else pointed this out. It works. But read on ....
The problem with all of these 'solutions' in C is that the compiler has
to reverse engineer the C back to the formal (semi-mathematical) loop
operation that the programmer was thinking of. In every compiler that
I have seen, there are a collection of heuristics to recognise the more
common loop constructions, and the rest are left to chance. If you use
a 'non-standard' one (however clean and otherwise wonderful), it will
usually produce poor code.
This is, after all, why the latest Fortrans are defining separate loop
constructs for when the order matters and when it doesn't.
Even if the address of the loop index is never taken, and
live-variable analysis shows the index to be dead at the loop's exit?
Tom Payne
In article <ECJuq...@kithrup.com>, s...@kithrup.com writes:
> In article <2076c.sm...@ziplink.net>,
> Scott Mayo <sm...@ziplink.net> wrote:
> ><3. We have mixing of declarations and code; you can declare a variable in the
> ><first (no-longer-expression) of a for loop, and its scope is the loop. It
> ><does *NOT* exist after the end of the loop. In general, objects can be
> ><declared at any point.
> >Thank you.
>
> That's not a "Thank you," that's an, "Oh my god, *WHY*?!?!"
>
> It doesn't make code more readable; it doesn't make it more maintainable;
> and it adds very little to compiler simplicity.
Oh yeah. Forcing variables to be declared a greater distance away from
where they are used helps readability *roll*.
I use unadorned {}'s every now and then just to keep the declarations
as close as possible to the use. Unfortunately, this confuses the
heck out of C newbies ("That's legal??") and introduces an unnecessary
level of nesting.
This:
{
<other vars>
int foo;
....
<code using foo>
}
is bad, this:
{
<other vars>
....
{
int foo;
<code using foo>
}
}
is an improvement, and this:
{
<other vars>
....
int foo;
<code using foo>
}
is how the language should have been in the first place. Of course, part of
the problem is that in C++, declarations are even less visually distinct
from expressions, especially when people write crap like:
Foo<bar<z> > x(z, b++);
("why aren't you using the value of the comparison?")
but that's C++'s problem, not C's.
---------------------------------------------------------------------------
Tim Hollebeek | Disclaimer :=> Everything above is a true statement,
Electron Psychologist | for sufficiently false values of true.
Princeton University | email: t...@wfn-shop.princeton.edu
----------------------| http://wfn-shop.princeton.edu/~tim (NEW! IMPROVED!)
spamming idiots please email sp...@franck.princeton.edu so I know who you are.
Thanks for being stupid and doing this automatically.
No, of course not. But the problems that I referred to are mainly
IN the control-flow analysis phases (and I DO mean PHASES)! Because
of the nature of C, it is a particularly gruesome task - anything
that can simplify it, and therefore improve its efficiency and
reliability, is desirable. Look, I am not pretending Fortran is
wonderful - it is actually pretty bad, too - but C is notoriously
nasty.
That's a matter of opinion, of course.
>As I understand it, I can write:
> for (int i = 0; i < N; i++) ...
>or
> for (int i = 0, j = N; i < j; i++, j--) ...
>but not
> for (int i = 0; long j = N; 1<<i < j; i++, j >>= 1) ...
Correct.
>Particularly if you can now throw in a
>declaration of i just before the loop,
A declaration just before the loop has a different scope to one in the
loop header.
>it's hard to see that the
>marginal convenience of a variable whose scope is exactly the for()
>justifies this enormous syntactic wart.
It's not a huge wart; it involves exactly one line in the syntax.
>Can definitions be inserted
>into if() or while()? If not why not?
Because there was no consensus on whether to use C++ syntax:
while (int i = x)
...
or a decl-expr syntax:
while (int i = N, j = X; i < j)
...
The C++ syntax limits you severely; since the test is that the declared
item is non-zero, it is much less likely to be used inside the loop or
if. The decl-expr syntax is more versatile, but totally unlike C++.
The C++ syntax would have been a slightly bigger win with switch(), but
no-one had enough interest to just do that.
Someone with a less suspicious mind might wonder how busy Dave Keaton
actually is.
All my C9X proposals and papers will appear on the web in the near
future.
> The feeling was that it is too soon; compilers allowing prototypes have
> only become common in the last few years, and there is a lot of legacy
> code.
I guess I have a hard time understanding this argument. I don't see why
there would be that many people who need to compile their legacy code with
a C9X compiler -- most vendors will need to keep shipping C89 (or older)
compilers for quite some time and legacy code should be compiled with
those compilers. If one felt a desperate need to take advantage of some
new C9X feature in their legacy code, tools like "mkproto" can be run first.
I don't see any great value in keeping old-style declarations/definitions
part of the standard.
Michael
>Someone with a less suspicious mind might wonder how busy Dave Keaton
>actually is.
I really meant "more suspicious" - I understand the situation perfectly. With
volunteers, you are getting more than you pay for, no matter what. However, it
is a bit frustrating to know all this stuff is going on that will significantly
affect my life, and not to be able, in this information age, to find out
anything about it.
>All my C9X proposals and papers will appear on the web in the near
>future.
Great! Please let us know when and where.
*NOTING* that it isn't properly linked into my site yet, and that not
all the documents are present yet:
<http://www.gold.net/users/cdwf/c/wg14papers.html>
Not necessarily. And maintaining a project where some files are compiled
with one compiler and some with another is a pain on Unix machines, and
nigh-on impossible on some Windoze "integrated" systems.
It's much easier to set aside a day/week/month to move the code to the
new C9X compiler. While waiting, you can start adding types and return
expressions to existing code using existing compilers.
A couple of details that I hope survived those cramped seats. Does an
inline function have an address? Must all instances of its address
have the same value regardless of which translation unit they are in?
Tom Payne
> >Note that if sizeof can evaluate its argument in the above, since the
> >"*p" argument has type "array of variable length", then the evaluation
> >of "*p" invokes undefined behavior, since p has not been initialized.
>
> I don't think it does in that case, because 'pointer to array' is
> probably of known size.
I didn't ask for the sizeof "pointer to array". I asked for the sizeof
array pointed to by pointer-to-array.
> Consider my change to your example and you'll see why it doesn't make any
> sense for the compiler to generate code to evaluate "x" in response to the
> sizeof operator. The size of the array must be somehow associated with
> the address of the array and to obtain that address the argument of the
> sizeof operator might need to be evaluated (in your example it *needs* to
> be evaluated).
>
Got it. Makes perfect sense now. Thanks.
ARGH!!!! I meant any type other than void here. Can't have an array of
void. Duh.
Yes to both. See another recent posting of mine on the topic.
> Not necessarily. And maintaining a project where some files are compiled
> with one compiler and some with another is a pain on Unix machines, and
> nigh-on impossible on some Windoze "integrated" systems.
I would expect most vendors to allow the linking of object files compiled
with different compilers quite easily (be they compilers for different
languages or just different implementations of the same language). I'm
fairly sure I can link object files compiled with gcc against those compiled
with HP's ANSI compiler.
Besides, if this doesn't seem to work, the maintainer would just compile
the new files with the existing C89 compilers.
Michael
At least one advantage of retaining old-style declarations is that
the POSIX function sigaction requires them (see Section 3.3.4 of
ISO/IEC 9945-1:1996). POSIX is trying to evolve sigaction to
eliminate the need for old-style declarations. I do not see how
they can do that without giving up some functionality.
Sincerely,
Bob Corbett
>> 5. We have variable length arrays.
>I'm interested in more details about this. Presumably committee
>members were familiar with Dennis Ritchie's 1989 paper "Variable-Size
>Arrays in C". ...
> - The proposal clearly violates the "spirit of C" in that it calls
> for complex run-time support. In essence the committee has
> mandated alloca(), and implementations will have to deal with
> all the tricky problems that implies, particularly in the
> presence of longjmp(). Ritchie gives this example:
> for (i = 1; i < 1000; i++) {
> int a[i];
> if (done())
> continue;
> }
> and notes that the compiler must notice the `continue' so as to
> release the storage of a[], and that the implementation must be
> able to deal with the case where done() calls longjmp(). Both
> of these mean that a minimal C compiler suddenly becomes a much
> more complex beast.
Certainly the committee was aware of Dennis's "fat pointer" approach.
There were in fact two competing VLA proposals for several years.
Both proposals had good and bad points. The proposal that was adopted
for C9x is largely based on actual implementation experience and user
feedback. I can't think of any other new language feature that has
been so thoroughly studied, debated, discussed, and refined. We think
that is is sufficiently useful and well engineered to propose for C9x.
Get hold of a review copy of the draft C9x when it comes out for public
review, or earlier via your WG14 national body, and if you find
problems we want to hear about them while there is time to fix them.
I don't think having to perform actions when the identifier goes out of
scope is a big deal. This is true already for auto variables. One way
to implement these critters is to run-time malloc their data and keep
just a fixed-size handle on the stack, which does smack of alloca() but
since the compiler is doing it it can be done 100% right (unlike user-
mode alloca() such as the one I contributed to the GNU project).
It is already true that a C9x implementation is noticably more comples
than an implementation of original C89. That's what happens when the
language accrues features to better support application areas that
were inadequately served by the previous version. The working model
for a compilation environment for C9x is a 512KB machine, up from the
64KB machine we attempted to accommodate with C89. (The target system
can still be small, e.g. microcontroller etc. although VLAs could pose
some interesting challenges for such environments.)
Personally, I am not quite as concerned with generating good code
(something that is eminently doable with modern technology) as I
am with providing the human programmer with a more direct expression
of the "operation that the programmer was thinking of". There are
sound practical reasons for desiring this property.
I suspect that you're too used to sensible systems.
>Besides, if this doesn't seem to work, the maintainer would just compile
>the new files with the existing C89 compilers.
Not if they want new features, they can't.
Nuts. I am am not referring to Douglas Gwyn's response. This whole
debate has been fueled since the days of the NCEG by two urban myths:
1) C is a simple language, and is easy to compile.
2) Dynamic sized arrays are complicated.
Both are complete nonsense. The ORIGINAL C compilers were simple, because
the specification was "they do what they do". X3J11 produced the FIRST
coherent specification of the C language, which included a lot of things
that were probably accidental in the original compilers. Subsequent
compilers have never been simple, because they have to conform to this
bizarre specification.
The second was used by the Fortran II fanatics to hammer Algol 60, and it
was repeatedly demonstrated to be total rubbish. Later languages showed
that such things do not make long jumps any harder than handling them in
the context of an OPTIMISED fixed-stack language. At WORST, they add a
word to the stack frame and two (cheap) operations to a function call.
The ONLY problem with VLAs in C has been fitting them into the bizarre and
unhelpful C model. In addition to the two main approaches thrashed to
death by the NCEG and X3J11, there were several other (less suitable) ones
and many variations of the main two. Most would have worked, but would
have needed extensive language hacks to fit them in.
Let us see the 'final' C9X proposal and judge it on its merits.
What was strsep() supposed to do? If it's useful, I'll add it to my own
library.
The comment about strdup() is a leg-pull, right? I mean, I see *VERY*
heavy use of it. Why is having something work _normally_ with free()
considered grounds for banning it?
> 3. We have mixing of declarations and code; you can declare a
> variable in the first (no-longer-expression) of a for loop, and its
> scope is the loop. It does *NOT* exist after the end of the loop. In
> general, objects can be declared at any point.
A major change like this, and they boggle at strdup(). Amazing.
> 5. We have variable length arrays. The expressions may have side
> effects, but it is unspecified whether and when they are produced.
> Do not put side effects you care about in the size expr of a VLA.
Hooray! C9x finally catches up with Algol 60!
> 6. We have compound literals. i.e.,
> asctime(&((struct tm) { .tm_year = 97 }));
> Yes, you can take their addresses.
Wonderful. Now in addition to return-array-out-of-extent bugs, we're
going to get return-compound-literal-out-of-extent bugs.
> 8. It is now a constraint violation for a return statement in a
> non-void function to not have an expression. YAY!!!!!
Hooray indeed.
--
Four policemen playing jazz on an up escalator in the railway station.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci.
>Not quite. In both cases an expressed view was that these functions
>don't *need* to be in the Standard; they are easy enough to write or
>provide in a user library. [If we'd been starting from scratch, much of
>the library would have been excluded for basically this reason.]
It is admittedly easy to write one's own strdup():
char *strdup(char const * s) {
size_t N = 1 + strlen(s);
char *p = malloc(N);
if (p) memcpy(p, s, N);
return p;
}
There are only two problems:
1) An implementation may already have swiped strdup() for something _else_
incompatible. I for one would like the standard to prevent this.
2) An implementation may stop me using this identifier because it is
reserved.
The ideal outcome would be for this function, which has by now been around
longer than some of the <string.h> lunacy that _was_ accepted in C89 had
been at the time, and is very wide-spread, to be in the standard.
The next best outcome would be for the standard to make sure that I can
use the existing name for this function and provide my own definition if
the implementation doesn't provide the operation.
>A secondary point was that strdup() on its own is insufficient - why not
>strndup(), stralloccat(), wcsdup(), memdup(), and so on ?
For a very simple reason, which was sufficient to get all sorts of really
strange stuff (like strtok() *SHUDDER*) into C89: *existing practice*.
We've had strdup() in a lot of C systems and a lot of C code for years.
We haven't had strndup() or memdup(). (Well, ok, so the string library
I posted years ago had them, but they never became popular.)
It would be a big win if it were true.
Face it, gcc -O2 -Wall, modern lint, and lclint *already* protect me from
uninitialised variables *far* more thoroughly than intermingled statements
and declarations ever can. What, after all, forces a late declaration to
be initialised?
>Plus, as a bonus, you no longer
>need keep around a pool of loop variables that risk getting misused;
>each loop variable is available where it's needed, *only* where it's
>needed.
You mean I couldn't write
{ int i;
for (i = 0; i < n; i++) {
...
}
}
before? Gosh, to think I never knew that. If I've loop variables of two
types (which I have often enough to care), I'm _still_ going to have to do
it the old way.
>ftp.dmk.com,
>in directory DMK/sc22wg14. (Someone with a more suspicious mind than mine might
>wonder why this site was maintained so assiduously since C9X was originally
>proposed, then abandoned just when major decisions started to be made . . .)
Because Dave Keaton is plenty busy, and not all proposers contributed
suitable online versions to the site.
Remember, this is all volunteer work (although some members get paid
to do the work, others like Dave do this work at their own expense).
Frankly, if someone wanted to be involved in the major decisions, he
could have done so. We had some new arrivals in the Committee, some
of whom are participating at their own expense because they think the
work is worth doing.
>In article <5p98n4$o...@news.inforamp.net>,
> pcu...@xacm.org (Peter Curran) wrote:
>
>>ftp.dmk.com,
>>in directory DMK/sc22wg14. (Someone with a more suspicious mind than mine might
>>wonder why this site was maintained so assiduously since C9X was originally
>>proposed, then abandoned just when major decisions started to be made . . .)
>
>Because Dave Keaton is plenty busy, and not all proposers contributed
>suitable online versions to the site.
As I've already said, I understand this. I should have kept this silly line to
myself - I apologize to Dave Keaton and associates for any pain caused.
>Frankly, if someone wanted to be involved in the major decisions, he
>could have done so. We had some new arrivals in the Committee, some
>of whom are participating at their own expense because they think the
>work is worth doing.
Beyond the problem of time, I should say that I really don't have much to
contribute to The Committee. I can recognize a problem when it hits me over the
head, but after voting against long long, I really wouldn't bring much to the
table. I took a couple of fourth-year compiler construction courses twenty-some
years ago, read SigPlan Notice for twenty-some years, read the "dragon book,"
fiddled around with lex and yacc a few times, and used a lot of C compilers to
write a lot of code. I don't think that adds up to much value to The Committee.
Inability to contribute is as much a reason as other commitments for staying
away.
<>>> 5. We have variable length arrays.
<>> - The proposal clearly violates the "spirit of C" in that it calls
<>> for complex run-time support.
< 1) C is a simple language, and is easy to compile.
< 2) Dynamic sized arrays are complicated.
<Both are complete nonsense.
I have my own touchstone for what is the "spirit of C". It's a slippery
one, but the upshot is that the spirit of C is assembly language.
Now put down the shotgun and listen. My belief is that a statement in
C always has a direct and obvious relationship to a very small number
of instructions. Everything, from the declarations of variables to
the switch statement, smells of tiny sequences of machine stuff, even
on RISC machines. It's always obvious just what a naive compiler would
lay down, sans optimization. Bored people can compile C in their heads,
for most machines. There is no hidden information and there are no surprises.
VLAs represent the very first exception I can think of. For the very first
time, the compiler is going to have to store an additional word of
information on the stack somewhere, to support sizeof(a) after int a[x].
And you wouldn't guess that that word exists unless you thought about
sizeof. It's a hidden datum - and C's never *done* that!
I'm still in favor of it - though the debugger writers, I imagine, won't
be overjoyed. But the "spirit of C" is definitely different now.
> I would expect most vendors to allow the linking of object files compiled
> with different compilers quite easily (be they compilers for different
> languages or just different implementations of the same language). I'm
> fairly sure I can link object files compiled with gcc against those compiled
> with HP's ANSI compiler.
For some weird reason, the words "structure passing conventions" seem to
flash before my eyes ...
Kai
--
Internet: k...@khms.westfalen.de
Bang: major_backbone!khms.westfalen.de!kai
http://www.westfalen.de/private/khms/
>Beyond the problem of time, I should say that I really don't have much to
>contribute to The Committee. I can recognize a problem when it hits me over
>the head, but after voting against long long, I really wouldn't bring much
>to the table. I took a couple of fourth-year compiler construction courses
>twenty-some years ago, read SigPlan Notice for twenty-some years, read the
>"dragon book," fiddled around with lex and yacc a few times, and used a lot
>of C compilers to write a lot of code. I don't think that adds up to much
>value to The Committee.
You'd me amazed. It sounds like you have experience comparable to mine. A
couple of the other non-vendor members have similar background.
Often, just someone who can, as you say, recognize a problem when hit over
the head with it, could make a big difference in a proposal. For instance,
if someone with even a couple hours to spend reviewing the wording had
been able to notice a couple of the omissions in the bool paper, we might
have had good enough wording that approving the bool type would have been
a few minutes' work, not more than an hour of debate.
One more person able to articulate why "long long" is worse than the problem
could have made the difference... I certainly wish I'd been around.
>Inability to contribute is as much a reason as other commitments for staying
>away.
I've met several people who I feel would be genuinely unable to contribute to
the C standards work. None of them are capable of writing code in C.
(For instance, look at Assembly Boy over in comp.lang.c; so clue free, you
find yourself thinking he must be synthetic, because in natural processes,
*some* clue always seeps in.)
More people to help with the work are always welcome. When we finally go to a
public review, we're going to be struggling very hard to get this done.
Admittedly, it's pricey. I managed to get a waiver on my dues, since I'm
doing this out of pocket, and as a result, I can afford to make three meetings
a year - out of pocket, and up til now I've been taking unpaid leave for it.
(My new job, starting Monday, will pay for part of my time, but my expenses
will still be out of pocket.) But on the other hand, how much better can
something look on the resume? :)
Think about it: Schildt is on the committee (not that he shows up or
contributes, he just pays dues), and people assume he's competent. If it
can make him seem competent, think of how much it can do for you!
-s
--
Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
I am not actually st...@quantcom.com but junk mail is accepted there.
The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.
It's like strtok, but the signature is
char * strsep(char **source_and_next, char *delim);
It returns the "next" string in *source_and_next, and
sets *source_and_next to the next string (or a null pointer).
>The comment about strdup() is a leg-pull, right? I mean, I see *VERY*
>heavy use of it. Why is having something work _normally_ with free()
>considered grounds for banning it?
Because of malloc wrappers.
Really, though, the thing that killed them both was lack of support.
They're both trivial, and there's a very vocal segment of the committee
that flatly opposes *ANY* change that can be implemented by a user.
vscanf is in because you *CANNOT* implement it without an underlying
implementation of it, or the patience to reimplement all of scanf.
No one has any trouble implementing strsep or strdup. So... Some people
provide them already, and don't care if they're in the standard, because
after all, you can always use them if they're around. Some people oppose
them. Some don't care.
>> 3. We have mixing of declarations and code; you can declare a
>> variable in the first (no-longer-expression) of a for loop, and its
>> scope is the loop. It does *NOT* exist after the end of the loop. In
>> general, objects can be declared at any point.
>A major change like this, and they boggle at strdup(). Amazing.
Language features are actually easier to convince some people of.
Anyway, it's not that major a change. :) Really. :)
>> 5. We have variable length arrays. The expressions may have side
>> effects, but it is unspecified whether and when they are produced.
>> Do not put side effects you care about in the size expr of a VLA.
>Hooray! C9x finally catches up with Algol 60!
I'm overall happy about it, but it does *really* bother me that sizeof()
is no longer a compile-time constant guaranteed not to evaluate its operand
in any way.
>> 6. We have compound literals. i.e.,
>> asctime(&((struct tm) { .tm_year = 97 }));
>> Yes, you can take their addresses.
>Wonderful. Now in addition to return-array-out-of-extent bugs, we're
>going to get return-compound-literal-out-of-extent bugs.
I don't think anyone's that stupid; you'd have to... Okay, they are that
stupid, I can see it happening.
I'll accept it for the sheer convenience. Now, for orthoganality, I want
the ability to take the address of any constant, and have this yield
the address of an anonymous auto variable initialized by the constant,
since this is actually a pretty cool feature if you have the patience
to comprehend it.
>> 8. It is now a constraint violation for a return statement in a
>> non-void function to not have an expression. YAY!!!!!
>Hooray indeed.
Yes. I just wish we could have had wording to make a constraint violation
out of falling off the end, but we didn't have good wording, and there is
opposition.
There was a proposal of allowing void main, and a proposal of requiring that
falling off the end of main indicate success. (The latter came from the DEC
rep, who is probably spoiled by VMS.) Both were defeated.
Also, and I'd like to publically thank Clive for this, the termination status
of an dropped-out-of main is now *UNSPECIFIED*, not *UNDEFINED*. This cleans
up one of my pet peeves.
>In article <5p98n4$o...@news.inforamp.net>,
> pcu...@xacm.org (Peter Curran) wrote:
>
>>ftp.dmk.com,
>>in directory DMK/sc22wg14. (Someone with a more suspicious mind than mine might
>>wonder why this site was maintained so assiduously since C9X was originally
>>proposed, then abandoned just when major decisions started to be made . . .)
>
>Because Dave Keaton is plenty busy, and not all proposers contributed
>suitable online versions to the site.
>
>Remember, this is all volunteer work (although some members get paid
>to do the work, others like Dave do this work at their own expense).
To pursue this just a little further . . . this site is described as the
"official archive" for C9X. There is also an "official" European mirror. I
don't think I was being unreasonable in expecting them to be maintained. I
don't know who gave them that designation, but if there really is some validity
to the claim to be "official," it seems to me that The Committee has some
obligation to make an effort to make things available there.
Incidentally, as far as I can see, there is nothing on the site that provides
any information about the "long long" proposal - not even that it *was* a
proposal for C9X. In fact, I have yet to find anything except the most basic
outline. I only heard that it was proposed after it was already accepted. If
some information had been provided to the C community about this, it might have
been easier to get participants for The Committee. As far as I can tell, this
is the most controversial piece of C9X, and the one most likely to get people
interested enough to get involved. (Perhaps that was why it was kept . . . no,
I won't say that :-)
Nothing forces it. However, if you adopt a style of only declaring a
variable when you have an initial value ready for it, uninitialized
variables stand out much more.
At present, absent tricks like opening new blocks all over the place
(leading either to massive indentation or ugly error-prone code), you
have to declare everything at the start. That means you either have
uninitialized variables around everywhere or you put dummy values in.
Yes, some compilers will do the flow analysis and tell you. Nonetheless,
I find it easier to write in the declare-when-needed style.
>>Plus, as a bonus, you no longer
>>need keep around a pool of loop variables that risk getting misused;
>>each loop variable is available where it's needed, *only* where it's
>>needed.
>You mean I couldn't write
> { int i;
> for (i = 0; i < n; i++) {
> ...
> }
> }
>before? Gosh, to think I never knew that.
Of course you could.
> If I've loop variables of two
>types (which I have often enough to care), I'm _still_ going to have to do
>it the old way.
True, but this still covers most cases.
> There are only two problems:
> 1) An implementation may already have swiped strdup() for something _else_
> incompatible. I for one would like the standard to prevent this.
> 2) An implementation may stop me using this identifier because it is
> reserved.
>
> The ideal outcome would be for this function, which has by now been around
> longer than some of the <string.h> lunacy that _was_ accepted in C89 had
> been at the time, and is very wide-spread, to be in the standard.
> The next best outcome would be for the standard to make sure that I can
> use the existing name for this function and provide my own definition if
> the implementation doesn't provide the operation.
How about this solution: Pretend, in new code, that strdup never
existed. The name is not in your namespace, so don't use it. Roll your
own and call it dupstr, or dupstring, or whatever.
> No one has any trouble implementing strsep or strdup. So... Some people
And what about ANSI 4.13?
> >> 8. It is now a constraint violation for a return statement in a
> >> non-void function to not have an expression. YAY!!!!!
>
> >Hooray indeed.
>
> Yes. I just wish we could have had wording to make a constraint violation
> out of falling off the end, but we didn't have good wording, and there is
> opposition.
How about simply saying that falling off the end is exactly equivalent to
doing a "return;"?
What problem am I not seeing here?
> There was a proposal of allowing void main, and a proposal of requiring that
> falling off the end of main indicate success. (The latter came from the DEC
> rep, who is probably spoiled by VMS.) Both were defeated.
Insanity.
Well, ok, how about making an explicit exemption for main, then? Not that
I see any use in doing main differently.
: >What, after all, forces a late declaration to be initialised?
:
: Nothing forces it. However, if you adopt a style of only declaring a
: variable when you have an initial value ready for it, uninitialized
: variables stand out much more.
And you may then be able to declare the variable "const", which some
of us enjoy.
--
John Rickard
> I'm overall happy about it, but it does *really* bother me that sizeof()
> is no longer a compile-time constant guaranteed not to evaluate its operand
> in any way.
What about keeping sizeof() the way it was, and inventing (say)
lengthof() that works with VLAs? Macros under C9X that would need to
work with everything would use lengthof().
Alternatively call the two constructs something like:-
sizeof() works with VLAs, as currently proposed etc.
static_sizeof() good-ole-sizeof, the way Seebs likes it :-)
> Alternatively call the two constructs something like:-
>
> sizeof() works with VLAs, as currently proposed etc.
> static_sizeof() good-ole-sizeof, the way Seebs likes it :-)
The reason I propose this is that it is yet another use for the word
"static". It is traditional that each C standard introduce another
additional use for it, yes? :-)
In article <wkyb7jv...@vggas.com>, James Youngman <JYou...@vggas.com> writes:
> <5pi16c$rru$2...@blackice.winternet.com> <wklo3j3...@vggas.com>
> NNTP-Posting-Host: uriel.vggas.com
> X-Newsreader: Gnus v5.3/Emacs 19.34
> Xref: cnn.Princeton.EDU comp.std.c:21924
Can someone explain to me a situation in which sizeof(something with a VLA)
is both (1) useful and (2) not easily replaced by an expression containing
the expression used to declare the VLA (possibly saved in a var if it could
change)?
I'd rather see sizeof(VLA) be a constraint violation, and keep sizeof() as
a constant ...
---------------------------------------------------------------------------
Tim Hollebeek | Disclaimer :=> Everything above is a true statement,
Electron Psychologist | for sufficiently false values of true.
Princeton University | email: t...@wfn-shop.princeton.edu
----------------------| http://wfn-shop.princeton.edu/~tim (NEW! IMPROVED!)
spamming idiots please email sp...@franck.princeton.edu so I know who you are.
Thanks for being stupid and doing this automatically.
Modulo your definition of 'easily':
One situation could be within a macro that takes the name of an object
and passes it to sizeof(). You can provide a second version of the macro
which takes a size argument instead. However, this is annoying and a
maintenance problem if the macro is complex, and may not even be
feasible if the macro is externally defined by someone else.
In either case, the macro might need to be rewritten to handle VLA's. It
should be a minor price to pay for a major convenience.
It's sort of a re-entrant strtok():
char *
strsep(stringp, delim)
char **stringp;
const char *delim;
{
char *str, *p;
if( str = *stringp ) {
if( p = strpbrk(str, delim) )
*p++ = '\0';
*stringp = p;
}
return str;
}
>The comment about strdup() is a leg-pull, right? I mean, I see *VERY*
>heavy use of it. Why is having something work _normally_ with free()
>considered grounds for banning it?
Speaking of string functions, what about case-insensitive versions of
search and comparison (stricmp, strnicmp, stristr) and case-conversion
functions (strupper, strlower)?
Regards,
Ingo
It is not clear yet just what the VLA proposal _is_.
I note that if you have a set of VLAs
T1 a1[k1*n+d1];
...
Tm am[km*n+dm];
where all the sizes are linear functions of a common varying subexpression,
you only need to store the value of that common subexpression. The other
constants can be absorbed into the scaling. E.g. given
... foo(int const n) {
int a[2*n];
double b[n+1];
...
a[] and b[] can share a _single_ word of overhead, and since n is declared
read-only (or rather, because n is not modified) that word can actually
_be_ n.
In short, I expect the common cases to have _zero_ overhead.
Certainly, the existing code I have using alloca()/malloc() to simulate
VLAs would need no extra space overhead when converted to VLA form.
Who said it was my code, or that I had the power to change it?
Fact is, strdup() is widely available and widely used. People have used
it for good reason, and _in practice_ it was very easy to port. All I'm
saying is that it would be nice if theory matched the practice.
void main() has also been mentioned. Well, there again, that's something
which nit-picking pedants like me have got letter-perfect from day one.
But it _is_ in wide-spread use, and is even recommended in far too many
textbooks. I think the fact is lamentable, but it _is_ a fact, and I think
that C9X really ought to legitimise void main(). Leaving it illegitimate
will do _nothing_ to stop the thousands of programmers who have been _taught_
to use void main(). main() is already a special case. void main() can be
handled along the lines of void main(<args>) <body> is equivalent to
static void <hidden>(<args>) <body>
int main(<args>) { <hidden>(<arg values>); return 0; }
Hmmm. I may have just talked myself into the view that providing a free
tool to fix the mistake would be almost as good. However, writing such a
tool is fairly hard.
Failing that, the standard's wording must say very very clearly that
void main() is an *error* that *must* be diagnosed.
<Failing that, the standard's wording must say very very clearly that
<void main() is an *error* that *must* be diagnosed.
I prefer this idea to legitimizing void main(). But if it is made legitimate,
I'd like to see something said about the "int" that gets returned
in environments that expect one. I know this falls on the very edge
of the standard. But the standard should mandate that, barring a call
to exit(), that void main() *appears* to return the "happy" value to
environments that expect to receive an int at the end of a
program's execution. Usually 0, though the standard wouldn't say
that quite baldly.
Otherwise, for a reason that isn't legislated by the standard, C code
written and working in one implementation will fail to be useful
in another, until recoded.
> Speaking of string functions, what about case-insensitive versions of
> search and comparison (stricmp, strnicmp, stristr) and case-conversion
> functions (strupper, strlower)?
I would definitely recommend leaving these out of the _C_ standard. If you
only consider letters A-Z and a-z, they are trivial (except that the C
standard doesnt guarantee that the codes for 'A' to 'Z' and 'a' to 'z' are
in any way related to each other).
If you consider alphabets with more letters then you get into a real big
mess quite quickly. For example, an alphabet might contain only a
lowercase version of some letters (that means an uppercase version
obviously exists, but it is not in that particular character set). There
are funny things like the lowercase dotless i (I dont even try to type it,
just imagine an i without the dot). What should happen when you convert
that to uppercase and back to lowercase?
This is definitely something that the C standard shouldnt worry about, it
is more something for the Unicode standard, for example.
-- For email responses, please remove the last emm from my address.
-- For spams, please send them to whereever...@but.not.here
Yes, it does, but for the "C" locale only.
|> If you consider alphabets with more letters then you get into a real big
|> mess quite quickly. For example, an alphabet might contain only a
|> lowercase version of some letters (that means an uppercase version
|> obviously exists, but it is not in that particular character set). There
|> are funny things like the lowercase dotless i (I dont even try to type it,
|> just imagine an i without the dot). What should happen when you convert
|> that to uppercase and back to lowercase?
|>
|> This is definitely something that the C standard shouldnt worry about, it
|> is more something for the Unicode standard, for example.
It gets better than that. There are languages (such as German!) where
one character can map into two and, for such languages, you need at
least a string-to-string conversion function. The current standard
facilities (toupper etc.) are pretty well useless except in the "C"
locale or minor extensions of that.
In SHARE Europe, we had known this for a good many years, and some of
us tried to get the 1989 C standard fixed. We failed. To be fair to
X3J11, C is not the only language that has made a cock-up of this
area, and where the people who knew about the problem failed to get
the real issues addressed.
I agree with you that the C standard should not attempt to make a bad
situation worse by adding on yet more half-baked facilities, based on
an inadequate and inextensible model.
I am interested in the details of the VLA proposal. For example, is
an implementation ever required to free the storage allocated to a
VLA or is that just a quality-of-implementation issue? I am
concerned about cases such as longjmps over routines that declare
VLAs. If longjmps are required to free the VLAs, the idea of
mallocing space for VLAs looks untenable for many systems. Doing
the equivalent of an alloca is tenable, but it presents the
possibility of interfering with user-specified allocas. Consider
the function
void foo(void)
{
...
for (i = 1; i < n; ++i)
{
real a[i];
...
p = alloca(64);
...
}
...
bar(p);
}
Space allocated using alloca remains allocated over the lifetime
of the routine that called alloca. My understanding is that the
lifetime of a VLA is the closest containing compound statement.
If stack space is used for both VLAs and alloca, the stack is no
longer LIFO (which, to me, means it is not a stack).
I know that alloca is not part of standard C and probably never
will be. I never use alloca. Nonetheless, I have heard that
some popular programs do use alloca.
Sincerely,
Robert Corbett
This does look like a conflict. But should the C standard be held back
because of a conflict with a nonstandard feature. Particularly the
nonstandard feature that the new feature is intended to replace?
It seems unlikely that a single function would need to use both alloca()
and VLA. And it's fairly easy to find alloca's, so if you're adding VLA to
a function you can probably replace the alloca with an appropriate use of
VLA.
--
Barry Margolin, bar...@bbnplanet.com
BBN Corporation, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
So call it something else. Problem solved.
>The ideal outcome would be for this function, which has by now been around
>longer than some of the <string.h> lunacy that _was_ accepted in C89 had
>been at the time, and is very wide-spread, to be in the standard.
[...]
>For a very simple reason, which was sufficient to get all sorts of really
>strange stuff (like strtok() *SHUDDER*) into C89: *existing practice*.
So why was it left out first time round ? What's changed ?
There are platforms where legitimising it would be a lot of work
(because of the way they lay out the stack).
>Failing that, the standard's wording must say very very clearly that
>void main() is an *error* that *must* be diagnosed.
However, it doesn't. And it would have to be special-cased to do so.
[This is harder than you think; consider "static void main (float);"]
Actually, the new wording clearly *allows* an implementation to permit
it to work. But does not require it. And implementations where it
doesn't can still generate an error if they want.
And probably more than mine.
>Admittedly, it's pricey.
Actually, that's purely a US situation. The UK doesn't charge for
belonging to IST/5/-/14. I don't think most other countries do either.
If you are accredited, there is no charge for attending WG14 meetings
other than your own expenses.
>But on the other hand, how much better can
>something look on the resume? :)
I've got bad news for you ...
Hmm. You try correctly implementing unsigned arithmetic on a one's
complement machine without the relevant opcodes. Or long on a 16 bit
platform. Or longjump on lots of implementations.
>And you wouldn't guess that that word exists unless you thought about
>sizeof.
There's lots of things you wouldn't think about if you didn't read the
Standard properly. The section on sizeof clearly mentions the issue, and
a minute's thought on how to implement it will show the size must be
kept around.
>It's a hidden datum - and C's never *done* that!
Oh ? Tried implementing a function returning a structure without one ?
Returning *any* storage is a Q-o-I issue. Even x in:
unsigned long i;
for (i = 0; i < ULONG_MAX; i++)
{
char x;
x = i & 1;
}
>I am
>concerned about cases such as longjmps over routines that declare
>VLAs. If longjmps are required to free the VLAs, the idea of
>mallocing space for VLAs looks untenable for many systems.
It's Q-o-I again. Personally, I would expect the space to be correctly
freed after a longjmp().
>Doing
>the equivalent of an alloca is tenable, but it presents the
>possibility of interfering with user-specified allocas.
Hmm. Perhaps we have a reason to eliminate alloca() !
There are other possible approaches, such as maintaining a chain of
pointers to allocated space for use when leaving a function, and walking
the chain as part of longjmp().
Indeed. A large can of snakes waits to bite you.
>If you
>only consider letters A-Z and a-z, they are trivial (except that the C
>standard doesnt guarantee that the codes for 'A' to 'Z' and 'a' to 'z' are
>in any way related to each other).
The codes, no. But "toupper('a') == 'A'" must be nonzero, at least in
the C locale (I need to think carefully before saying "in all locales").
>If you consider alphabets with more letters then you get into a real big
>mess quite quickly. For example, an alphabet might contain only a
>lowercase version of some letters (that means an uppercase version
>obviously exists, but it is not in that particular character set).
Not to mention issues like German eszet, which uppercases to "SS", Dutch
"ij" which uppercases in various ways according to context (and
country), Greek's two different lowercase 's's, ...
In French, lowercasing the string "SUR" has two different results
depending on textual context (the 'u' might or might not carry a
circumflex).
Doesn't it also handle multiple delimiters differently ?
>Really, though, the thing that killed them both was lack of support.
>They're both trivial, and there's a very vocal segment of the committee
>that flatly opposes *ANY* change that can be implemented by a user.
The library is already two or three times as large as C89's. The last
draft I looked at was over 400 pages long, and almost all of that is in
the library section.
>>A major change like this, and they boggle at strdup(). Amazing.
>Language features are actually easier to convince some people of.
Partly because they are impossible to provide any other way (short of
writing your own C9X-front :-).
>>> 6. We have compound literals. i.e.,
>>> asctime(&((struct tm) { .tm_year = 97 }));
>>> Yes, you can take their addresses.
>>Wonderful. Now in addition to return-array-out-of-extent bugs, we're
>>going to get return-compound-literal-out-of-extent bugs.
>I don't think anyone's that stupid; you'd have to... Okay, they are that
>stupid, I can see it happening.
We already get return-pointer-to-freed-memory bugs and return-pointer-
to-block-scope-variable bugs. Nothing's new.
>Also, and I'd like to publically thank Clive for this, the termination status
>of an dropped-out-of main is now *UNSPECIFIED*, not *UNDEFINED*. This cleans
>up one of my pet peeves.
You're welcome.
Now for the other 27 pet peeves of mine ....
>In article <5pfm4g$cv3$1...@goanna.cs.rmit.edu.au>, "Richard A. O'Keefe"
><o...@goanna.cs.rmit.edu.au> writes
<snip - we're talking about strdup>
>>For a very simple reason, which was sufficient to get all sorts of really
>>strange stuff (like strtok() *SHUDDER*) into C89: *existing practice*.
>
>So why was it left out first time round ? What's changed ?
Sorry, but I have to tie this to my pet peeve - "long long." The only
justification I have ever seen presented for this is "existing practice."
(Note, I am referring to the "long long" syntax, not 64-bit ints, for which
there is lots of justification.) So - what's changed? (This is rhetorical, of
course - it is too late for the answer in either case to matter.)
<In article <209ba.sm...@ziplink.net>, Scott Mayo
<<sm...@ziplink.net> writes
<>My belief is that a statement in
<>C always has a direct and obvious relationship to a very small number
<>of instructions. Everything, from the declarations of variables to
<>the switch statement, smells of tiny sequences of machine stuff, even
<>on RISC machines.
<Hmm. You try correctly implementing unsigned arithmetic on a one's
<complement machine without the relevant opcodes. Or long on a 16 bit
<platform. Or longjump on lots of implementations.
I confess to finding one's complement machines very, very amusing.
And implementing long in 16 bits is easy. The C standard makes it
very easy indeed. Too easy. But in general, the instructions
you have to use for all this are only awkward, not an Utter Mystery.
I suppose that's a better summartion of the spirit of C: from the
programmer's point of view, there are no Utter Mysteries.
Except longjmp. longjmp should be taken out behind the barn and shot.
<>And you wouldn't guess that that word exists unless you thought about
<>sizeof.
<>It's a hidden datum - and C's never *done* that!
<Oh ? Tried implementing a function returning a structure without one ?
That's not any more hidden than any automatic variable. It has to exist,
somewhere, just like any other returned value. In some languages, the name of
the function itself stands in for this stack space, making it very
explicit indeed. (*)
VLA sizes aren't the same. AFAIK, the size of the VLA is maintained ONLY
for use with sizeof - a special and subtle case in an otherwise clear
language.
Radical idea: if sizeof won't work with malloc'd memory, why *should*
it work with VLAs? (I'd be happier if there was some way that sizeof
*could* work with malloc'd memory, of course, though no syntax for
it springs to mind. But at least everything could be consistant.)
(*) And last I checked, the standard was unassertive, or in denial, about
struct X {..int bar;..};
struct X foo() {.....}
void y(void)
{
int z = foo().bar;
.....
}
because the space to hold foo()'s return long enough to pluck
the .bar from it was too mysterious to comtemplate. And if that's
too mysterious for C, where does this hidden array size value fall?
If this is addressed, let it return an unspecified value, rather than
0. If you want to return 0, code it with a proper return type and
value. ;-) In most cases, that won't require an changes to current
compilers.
>Failing that, the standard's wording must say very very clearly that
>void main() is an *error* that *must* be diagnosed.
That, of course, would apply only to hosted implementations.
--
Thad
(Programmer of standalone systems)
To be followed by "result return conventions", "naming conventions",
"library symbol conflicts", "standard I/O handling", "signal handling",
"long jumping" and ....
Mark Twain had an advertising poster that said: "A parade of elephants
may be expected". At the bottom, in much smaller type, it said: "In
fact, the public is privileged to expect whatever it pleases."
I have been in this area, as developer, consultant, user, implementor
and so on for 25 years. It is JUST ABOUT possible to get Fortran 77 and
C to interwork, if you don't worry about standards conformance in mixed
language programs. A very, very few vendors add some similar languages
(e.g. PL/I or Cobol), but as for C++ and Fortran 90!
>In article <5psrep$mcc$1...@goanna.cs.rmit.edu.au>, "Richard A. O'Keefe"
><o...@goanna.cs.rmit.edu.au> writes
>>I think the fact is lamentable, but it _is_ a fact, and I think
>>that C9X really ought to legitimise void main().
>There are platforms where legitimising it would be a lot of work
>(because of the way they lay out the stack).
That *CANNOT* be true. In a previous message, I outlined a trivial
source-to-source transformation, well within the scope of any compiler,
that will make it work. The thing that is _called_ main in the source
code does NOT have to be the thing that is directly invoked by the
startup code.
>>Failing that, the standard's wording must say very very clearly that
>>void main() is an *error* that *must* be diagnosed.
>However, it doesn't. And it would have to be special-cased to do so.
>[This is harder than you think; consider "static void main (float);"]
>Actually, the new wording clearly *allows* an implementation to permit
>it to work. But does not require it. And implementations where it
>doesn't can still generate an error if they want.
BUT THIS IS PRECISELY THE SHITTY STATE OF AFFAIRS THAT NEEDS TO BE FIXED.
Either void main() should be legal in all C9X implementations (which would
break the least amount of existing code) or it should be illegal in all
C9X implementations. The situation where the commonest way of declaring
main(), preached in a shocking number of textbooks, cannot be made to work
(according to you) on some systems, is not a tolerable situation.
Let me say again: a compiler can rewrite declarations and definitions of
main() with a 'void' result to declaratations and definitions of '__main'
(or some other name), and a linker can pull in a default definition of
'main' that _is_ compatible with the stack layout and then does a perfectly
ordinary call to the __main function. Compilers must _already_ special-
case main() on some systems because of the freedom allowed with the
argument list.
C already addresses the Turkish I problem effectively via the locale
mechanism. There are of course other problems: consider the letter
(and I do mean letter, even though its written with two symbols) "dj".
It has _three_ forms:
lower case "dj"
upper case "DJ"
title case "Dj"
and it is one of several such letters. If case conversion functions
were to be provided, there would have to be three of them: to upper
case, to lower case, and to title case.
>In article <5pfm4g$cv3$1...@goanna.cs.rmit.edu.au>, "Richard A. O'Keefe"
><o...@goanna.cs.rmit.edu.au> writes
>>It is admittedly easy to write one's own strdup():
>[...]
>>There are only two problems:
>So call it something else. Problem solved.
This sort of sneering dismissal isn't good enough.
As I said in a previous posting,
A) strdup() has been part of several major C implementations for a long time.
There is *better* precedent for strdup() now than there was for strtok()
when _that_ abomination was put in C89.
B) People keep on assuming that I am talking about *my* code and that I
am free to change it. Neither of these assumptions is warranted or
true.
>>For a very simple reason, which was sufficient to get all sorts of really
>>strange stuff (like strtok() *SHUDDER*) into C89: *existing practice*.
>So why was it left out first time round ? What's changed ?
One thing that has changed is that we have now had 8 more years and
more implementations and many many more people using strdup().
The C committee is adding all sorts of wonderful new stuff to C, and
that's fine (as long as it doesn't add so _much_ new stuff that it
delays compilers too long). But it should also do what the C89
committee did so well, which was to codify existing practice where
possible. Ok, existing practice _is_ clear here.
As for the business about malloc() wrappers, I really don't understand.
It was my understanding that C89 had made it pretty well impossible for
people to replace malloc().
<C already addresses the Turkish I problem effectively via the locale
<mechanism. There are of course other problems: consider the letter
<(and I do mean letter, even though its written with two symbols) "dj".
<It has _three_ forms:
< lower case "dj"
< upper case "DJ"
< title case "Dj"
<and it is one of several such letters. If case conversion functions
<were to be provided, there would have to be three of them: to upper
<case, to lower case, and to title case.
This is going to sound terribly snobbish and American, but let's give
it a try, anyway.
I sympathise deeply with the writers of Turkish. I'm sure there's is
a fine language with a fascinating history and much excellent poetry
and all the rest. But can we agree that C ought not to be held back
from general usefulness because Turkish has three cases and C has two?
I would like to see stricmp (and more?) in the standard. This is a case
of a set of functions that the end user *can't* get right, unless he puts
many months of effort into it. Between tricks in the character set,
(ASCII vs that odd IBM format), tricks in the language (everyone has their
favorite horror stories; insert them here), and the joy of multibyte
issues, the average programmer cannot be asked to write portable,
international code without assistance from the standards folk. I agree
the runtime can't get it right in all cases. But it should still be possible
to devise locales that cover many cases, and apologise to the rest of
the world. Given those locales, stricmp can do at least a good enough
job to accomodate most people's needs.
I agree that strlower is dicey; existing implementations smugly
assume the output length is equal to the input length. I suspect we
can't fix all C's problems in this area before C0X. But stricmp at
least as no such excuse, and just being able to compare strings is
probably 75% of where programs fall down when taken across borders.
Someday Unicode will be the mandate, the char type will be 16 bits
wide, and sizeof(byte_t) will be the definition of 1, so to speak.
Then we can make almost everyone happy. Until then, I'd like us just to
get closer.
> Actually, the new wording clearly *allows* an implementation to permit
> it to work. But does not require it. And implementations where it
> doesn't can still generate an error if they want.
>
Did the old wording ever *forbid* an implementation to permit it to
work? Since when does the Standard ever dictate what an implementation
must or must not do once undefined behavior is invoked?
--
Chris Volpe Phone: (518) 387-7766
GE Corporate R&D Fax: (518) 387-6560
PO Box 8 Email: "volpecr" AT "crd.ge.com"
Schenectady, NY 12301 Web: http://www.crd.ge.com/~volpecr
>I am concerned about cases such as longjmps over routines that declare
>VLAs. If longjmps are required to free the VLAs, the idea of
>mallocing space for VLAs looks untenable for many systems. Doing
>the equivalent of an alloca is tenable, but it presents the
>possibility of interfering with user-specified allocas.
...
>Space allocated using alloca remains allocated over the lifetime
>of the routine that called alloca.
Just change the semantics of alloca() to say that space allocated
with alloca() is also freed on exit from any scope which defines a VLA.
This is a backwards compatible change, since existing code doesn't
use VLAs.
This solution is the one adopted by GNU C, which has had VLA support
for years.
--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger f...@128.250.37.3 | -- the last words of T. S. Garp.
>As for the business about malloc() wrappers, I really don't understand.
>It was my understanding that C89 had made it pretty well impossible for
>people to replace malloc().
Nope, C89 made it impossible for people to _portably_ replace malloc().
But systems are allowed to let you replace malloc(), and many do.
There may even be portable programs that conditionally replace malloc()
only on systems that support this.
Adding strdup() to C9X might add latent bugs such programs. They wouldn't
break straight away, but they might break later on, when someone later
modifies the program to use strdup().
>Sorry, but I have to tie this to my pet peeve - "long long." The only
>justification I have ever seen presented for this is "existing practice."
>(Note, I am referring to the "long long" syntax, not 64-bit ints, for which
>there is lots of justification.) So - what's changed? (This is rhetorical,
>of course - it is too late for the answer in either case to matter.)
Well, for one thing, gcc supports `long long', in 1989 it didn't.
>>Sorry, but I have to tie this to my pet peeve - "long long." The only
>>justification I have ever seen presented for this is "existing practice."
>>(Note, I am referring to the "long long" syntax, not 64-bit ints, for which
>>there is lots of justification.) So - what's changed? (This is rhetorical,
>>of course - it is too late for the answer in either case to matter.)
>
>Well, for one thing, gcc supports `long long', in 1989 it didn't.
OK - I get it. Standard-compatible widely-used existing practice that is more
than 10 years old is not standardizable. Standard-incompatible limited-use
existing practice that is less than five years old is standardizable. Just so's
we understand :-)
>In article <5psrep$mcc$1...@goanna.cs.rmit.edu.au>, "Richard A. O'Keefe"
><o...@goanna.cs.rmit.edu.au> writes
>>I think the fact is lamentable, but it _is_ a fact, and I think
>>that C9X really ought to legitimise void main().
>
>There are platforms where legitimising it would be a lot of work
>(because of the way they lay out the stack).
I don't have any strong feelings on this issue, but I do have some comments on
the argument (which I have seen before, in various guises on various topics - I
am not trying to pick on this instance particularly).
The *first* requirement in the Standard Committee's Charter is:
Existing code is important, existing implementations are not.
It seems to me, reading the various discussion papers, that the Committee does
not really take this too seriously. This is not really surprising. I presume
that most of the committee members are implementors - they are the ones most
interested in the details of the standard, the ones with the most obvious costs
associated with changes, and a lot to lose if a standard incompatible with their
implementation is approved.
While not surprising, it would be more honest to remove the requirement from the
Charter. Regardless, though, in discussions of C9X, it should be clear that
arguements of the form "lots of people do that so it should be standardized" are
not going to make it, if "it" is incompatible with a major implementation
(whether you know it or not.) Complaints about C9X proposals better have a
stronger basis than that.
In article <5q09lu$n...@mulga.cs.mu.OZ.AU>, f...@mundook.cs.mu.OZ.AU writes:
>
> Nope, C89 made it impossible for people to _portably_ replace malloc().
> But systems are allowed to let you replace malloc(), and many do.
> There may even be portable programs that conditionally replace malloc()
> only on systems that support this.
And in fact I maintain a program that avoids strdup() for exactly that
reason. BTW, there are libc's out there that call malloc() from
within stdio functions (luckily, they are rare). This is _evil_ :-)
I would love to have library function X can/cannot call library
function Y spelled out in the standard, and be allowed to replace any
arbitrary one of them. Interestingly, the C++ standard was slowly
moving in this direction last time I looked (see the 'replaceable'
entries in the library portion in the draft standard).
---------------------------------------------------------------------------
Tim Hollebeek | Disclaimer :=> Everything above is a true statement,
Electron Psychologist | for sufficiently false values of true.
Princeton University | email: t...@wfn-shop.princeton.edu
----------------------| http://wfn-shop.princeton.edu/~tim (NEW! IMPROVED!)
spamming idiots please email sp...@franck.princeton.edu so I know who you are.
Thanks for being stupid and doing this automatically.
Could the same problem occur with variable length arrays? Or are they
forbidden from using malloc?
--
David Tanguay d...@Thinkage.on.ca http://www.thinkage.on.ca/~dat/
Thinkage, Ltd. Kitchener, Ontario, Canada [43.24N 80.29W]
> To be followed by "result return conventions", "naming conventions",
> "library symbol conflicts", "standard I/O handling", "signal handling",
> "long jumping" and ....
Well, I could be wrong about being able to link gcc-compiled objects with
"HP cc"-compiled objects, but HP publishes a "PA-RISC Procedure Calling
Conventions" document whose purpose is to allow for the linking of objects
compiled by different compilers (the document explicitly mentions
FORTRAN, Pascal, and ANSI C) with the expectation that these conventions
be followed even by non-HP-supplied compilers (like gcc). Maybe HP is unique
in this area of wanting complete compatibility between object files produced
for PA-RISC -- other vendors might not care as much (is there an "x86
Procedure Calling Conventions" document?).
Michael