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

Any plans to remove obsolescent features?

22 views
Skip to first unread message

Keith Thompson

unread,
Nov 16, 2009, 3:02:37 AM11/16/09
to
I understand that the committee has voted to remove gets() from the
upcoming C 201X standard (and there was much rejoicing).

Are there any thoughts of removing any other obsolescent or deprecated
features? I'm thinking specifically of old-style function
declarations, but there are several other examples in C99 6.11 (Future
language directions) and 7.26 (Future library directions). I think
the following is a complete list:

Declaring an identifier with internal linkage at file scope
without the static storage-class specifier

Restriction of the significance of an external name to fewer
than 255 characters (considering each universal character name
or extended source character as a single character)

The placement of a storage-class specifier other than at the
beginning of the declaration specifiers in a declaration

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators)

The use of function definitions with separate parameter
identifier and declaration lists (not prototype-format parameter
type and identifier declarators)

The ability to undefine and perhaps then redefine the macros
bool, true, and false

The gets function (already mentioned; this is in N1256, but
not in C99)

The use of ungetc on a binary stream where the file position
indicator is zero prior to the call

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Dag-Erling Smørgrav

unread,
Nov 16, 2009, 4:58:07 AM11/16/09
to
Keith Thompson <ks...@mib.org> writes:
> The ability to undefine and perhaps then redefine the macros
> bool, true, and false

How would you implement this?

I'd rather see them turned into keywords...

DES
--
Dag-Erling Smørgrav - d...@des.no

BGB / cr88192

unread,
Nov 17, 2009, 12:55:24 AM11/17/09
to

"Keith Thompson" <ks...@mib.org> wrote in message
news:ln1vjyj...@nuthaus.mib.org...

>I understand that the committee has voted to remove gets() from the
> upcoming C 201X standard (and there was much rejoicing).
>

yep, seems good to me.


> Are there any thoughts of removing any other obsolescent or deprecated
> features? I'm thinking specifically of old-style function
> declarations, but there are several other examples in C99 6.11 (Future
> language directions) and 7.26 (Future library directions).

yeah, those things should IMO go away anyways, but then after encountering
some late-90s code using these style declarations, it is possible that some
code will have to be modified, and a few people here and there will have to
learn to not write such things.

then again, it will probably take far longer for compilers to bother to
remove it (or be replaced by compilers which don't bother), and so by the
time it actually starts to matter, this syntax will presumably have almost
entirely disappeared anyways.

so, the change would mostly be a statement that people writing new compilers
need not bother worrying about implementing it I guess...


> I think
> the following is a complete list:
>
> Declaring an identifier with internal linkage at file scope
> without the static storage-class specifier
>

this one would likely break lots of code...


> Restriction of the significance of an external name to fewer
> than 255 characters (considering each universal character name
> or extended source character as a single character)
>

I disagree, there are cases where very long names can be useful, such as
with mechanically generated code with some amount of mangled data embedded
into the name (consider for example JNI, or trans-compiling Java '.class'
files into C).


> The placement of a storage-class specifier other than at the
> beginning of the declaration specifiers in a declaration
>

seems reasonable enough.


> The use of function declarators with empty parentheses (not
> prototype-format parameter type declarators)
>

I personally dislike this idea.

I would rather have the empty parenthesis be redefined to mean the same
thing as "(void)", since this would make things more consistent with nearly
every other language (in pretty much every other language, "()" means "no
arguments", whereas "(void)" is a C-ism...).

similarly, this one would probably break lots of code, since from what I
have seen "()" is a far more common practice than "(void)".


> The use of function definitions with separate parameter
> identifier and declaration lists (not prototype-format parameter
> type and identifier declarators)
>

this is what was meant originally.
I agree on this one at least.


> The ability to undefine and perhaps then redefine the macros
> bool, true, and false
>

errm...
I agree with the other poster that maybe these could instead be keywords.
but, then again, this could make issues with some existing code, so it is an
awkward issue.


> The gets function (already mentioned; this is in N1256, but
> not in C99)
>

gets can go away.


> The use of ungetc on a binary stream where the file position
> indicator is zero prior to the call
>

errm, is doing this anything other than a bug?...

lawrenc...@siemens.com

unread,
Nov 17, 2009, 8:56:39 AM11/17/09
to
Keith Thompson <ks...@mib.org> wrote:
>
> Are there any thoughts of removing any other obsolescent or deprecated
> features? I'm thinking specifically of old-style function
> declarations, but there are several other examples in C99 6.11 (Future
> language directions) and 7.26 (Future library directions).

Not to my knowledge. But I didn't know anyone was going to propose
removing gets() until it happened, either. :-)
--
Larry Jones

I think grown-ups just ACT like they know what they're doing. -- Calvin

Flash Gordon

unread,
Nov 17, 2009, 1:41:36 PM11/17/09
to
lawrenc...@siemens.com wrote:
> Keith Thompson <ks...@mib.org> wrote:
>> Are there any thoughts of removing any other obsolescent or deprecated
>> features? I'm thinking specifically of old-style function
>> declarations, but there are several other examples in C99 6.11 (Future
>> language directions) and 7.26 (Future library directions).
>
> Not to my knowledge. But I didn't know anyone was going to propose
> removing gets() until it happened, either. :-)

I think it is about time to remove some of the things which were
deprecated in 1989 at least. I agree with the poster who suggested
making an empty parameter list mean no parameters (void) rather than an
unspecified number of parameters. It would wind up one of my colleagues
if it was implemented before he retired, but I don't think that is
likely since he's in his fifties ;-)
--
Flash Gordon

Wojtek Lerch

unread,
Nov 17, 2009, 2:27:01 PM11/17/09
to
"Flash Gordon" <sm...@spam.causeway.com> wrote in message
news:0c7bt6x...@news.flash-gordon.me.uk...

> I think it is about time to remove some of the things which were
> deprecated in 1989 at least. I agree with the poster who suggested making
> an empty parameter list mean no parameters (void) rather than an
> unspecified number of parameters.

I think it would be wiser to do it in two steps -- make it a syntax error
first, and then re-introduce it with the new meaning in the next version of
the standard. This would give compilers a few years of freedom to choose
whether to support the old semantics or the new as an extension.

Eric Sosman

unread,
Nov 17, 2009, 3:28:54 PM11/17/09
to

This seems to overestimate the Standard's power to dictate
terms. The rapidity of C99's adoption is a sobering example of
how slavishly the vendors and developers follow the Standard's
decrees ...

Keep in mind, too that multiple Standards -- you're talking
about *four* of them! -- imply multiple definitions of what "C"
means. That is, multiple Standards create portability problems
rather than alleviating them. Having four Standards wouldn't be
as bad as the pre-ANSI chaos, but it wouldn't be as good as the
post-ANSI pre-C99 calm, either.

--
Eric Sosman
eso...@ieee-dot-org.invalid

BGB / cr88192

unread,
Nov 17, 2009, 4:50:41 PM11/17/09
to

"Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
news:7mgbo7F...@mid.individual.net...

I disagree...

since, as I see it, "()" has 2 meanings at the same time:
"()" as an empty list (implicit, but common);
"()" as an arbitrary number (official, but uncommon).

there is a very large amount of code which uses the former definition, but
almost no code I have seen which (intentionally) uses the latter (although,
programmers may sometimes stumble across it on accident, and then end up
assuming it to be some kind of compiler bug...).

the former case is implicitly contained in the latter, where the former is
the common understanding and usage, and the latter is what is officially in
the standard.

so, FWIW, it would be more a matter of deprecating a "bug" than of
introducing (conceptually) new semantics.


if compilers were to make "()" a syntax error, OTOH, a rather large amount
of code would break, so much so that likely almost no compiler
project/vendor would likely consider doing so (it is worth noting that the
general adoption of the "(void)" convention has been rather sparse IME, and
personally I don't feel it to be the right direction either, ...).

Francis Glassborow

unread,
Nov 17, 2009, 5:55:35 PM11/17/09
to
BGB / cr88192 wrote:

>
> if compilers were to make "()" a syntax error, OTOH, a rather large amount
> of code would break, so much so that likely almost no compiler
> project/vendor would likely consider doing so (it is worth noting that the
> general adoption of the "(void)" convention has been rather sparse IME, and
> personally I don't feel it to be the right direction either, ...).
>
>
>

It would also cause a great deal of difficulty to those people (and
there are a surprisingly large number of them including major software
developers) who need compatibility between C and C++

BGB / cr88192

unread,
Nov 17, 2009, 6:18:45 PM11/17/09
to

"Francis Glassborow" <francis.g...@btinternet.com> wrote in message
news:VK6dnUrsM6BwtJ7W...@bt.com...

yes, agreed...

I would have mentioned this as well, but I was not certain whether or not
common C++ compilers also accepted "(void)", but if not, then this is all
the more reason to either leave it alone, or simply adjust the semantics to
be more like other languages, but not to remove this syntax.

Wojtek Lerch

unread,
Nov 17, 2009, 10:50:07 PM11/17/09
to
"Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
news:hdv14v$mon$1...@news.eternal-september.org...

> Wojtek Lerch wrote:
>> "Flash Gordon" <sm...@spam.causeway.com> wrote in message
>> news:0c7bt6x...@news.flash-gordon.me.uk...
>>> I think it is about time to remove some of the things which were
>>> deprecated in 1989 at least. I agree with the poster who suggested
>>> making an empty parameter list mean no parameters (void) rather than an
>>> unspecified number of parameters.
>>
>> I think it would be wiser to do it in two steps -- make it a syntax error
>> first, and then re-introduce it with the new meaning in the next version
>> of the standard. This would give compilers a few years of freedom to
>> choose whether to support the old semantics or the new as an extension.
>
> This seems to overestimate the Standard's power to dictate
> terms. The rapidity of C99's adoption is a sobering example of
> how slavishly the vendors and developers follow the Standard's
> decrees ...

And do you think the next standard would improve things if it assigned a
different meaning to the old syntax, forbiding compilers to keep
interpreting it the old way as an extension?

> Keep in mind, too that multiple Standards -- you're talking
> about *four* of them! -- imply multiple definitions of what "C"
> means. That is, multiple Standards create portability problems
> rather than alleviating them. Having four Standards wouldn't be
> as bad as the pre-ANSI chaos, but it wouldn't be as good as the
> post-ANSI pre-C99 calm, either.

Yes, especially if you have multiple standards that assign conflicting
semantics to the same syntax. If one standard at least allowed, as an
extension, the semantics required by the other standard, wouldn't that make
things less bad?


Wojtek Lerch

unread,
Nov 17, 2009, 10:50:45 PM11/17/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:hdv5ri$49d$1...@news.albasani.net...

>
> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
> news:7mgbo7F...@mid.individual.net...
>> "Flash Gordon" <sm...@spam.causeway.com> wrote in message
>> news:0c7bt6x...@news.flash-gordon.me.uk...
>>> I think it is about time to remove some of the things which were
>>> deprecated in 1989 at least. I agree with the poster who suggested
>>> making an empty parameter list mean no parameters (void) rather than an
>>> unspecified number of parameters.
>>
>> I think it would be wiser to do it in two steps -- make it a syntax error
>> first, and then re-introduce it with the new meaning in the next version
>> of the standard. This would give compilers a few years of freedom to
>> choose whether to support the old semantics or the new as an extension.
>>
>
> I disagree...
>
> since, as I see it, "()" has 2 meanings at the same time:
> "()" as an empty list (implicit, but common);

Do you mean common outside of C, or commonly misinterpreted in C?

> "()" as an arbitrary number (official, but uncommon).

I remember it being fairly common. Before ANSI C it was the only way to
declare a fuction in C.

> there is a very large amount of code which uses the former definition, but

Again, in C??? Or in C++, Java, etc?

> almost no code I have seen which (intentionally) uses the latter
> (although, programmers may sometimes stumble across it on accident, and
> then end up assuming it to be some kind of compiler bug...).

What do you call people who actually understand the tools that they're
using? "Professional programmers", as opposed to just "programmers"? ;-)

> the former case is implicitly contained in the latter, where the former is
> the common understanding and usage, and the latter is what is officially
> in the standard.

Well my experience of what is "common" seems to differ from yours.

> so, FWIW, it would be more a matter of deprecating a "bug" than of
> introducing (conceptually) new semantics.

Apparently my definition of "bug" differs from yours as well.

> if compilers were to make "()" a syntax error, OTOH, a rather large amount
> of code would break, so much so that likely almost no compiler
> project/vendor would likely consider doing so (it is worth noting that the
> general adoption of the "(void)" convention has been rather sparse IME,
> and personally I don't feel it to be the right direction either, ...).

I didn't say that compilers would have to reject "()" as a syntax error; on
the contrary, I did talk about letting them interpret "()" either the old
way or the new way, as an extension. Just like compilers can still support
implicit int even though it was removed in C99. A lot of extensions look
like syntax errors to the standard; many of them (like "long long" or "for
(int i=0;;)") become part of another version of the standard.

Wojtek Lerch

unread,
Nov 17, 2009, 10:51:16 PM11/17/09
to
"Francis Glassborow" <francis.g...@btinternet.com> wrote in message
news:VK6dnUrsM6BwtJ7W...@bt.com...

I guess it could matter to code that is carefully crafted (or, more likely,
machine-generated) to be both standard C and standard C++ and not to rely on
any extensions. To most other code that still uses "()", the practical fact
that all compilers accept "()" and interpret it either the old (pre-ANSI C)
or the new (C++) way would not be a bigger problem than the fact that it's a
deprecated syntax in C.

Eric Sosman

unread,
Nov 18, 2009, 12:16:19 AM11/18/09
to

Perhaps I have misunderstood your suggestion, which I read
as proposing two changes in two successive Standards. C1x would
outlaw a construct that is well-defined (albeit "obsolescent")
in C90 and C99, then C2x would give the abandoned construct a
new meaning different from that it now has. C2x would be an
"extension" from the viewpoint of C1x, but both C1x and C2x would
be "incompatible changes" from the standpoint of C90 and C99.

Also, I reiterate my skepticism about the power of the
Standard to "forbid" things. A Standard that breaks existing
correct code will meet resistance, even if the breakage arises
from good intentions; consider the C99 experience. Of course,
it should be noted that C99 broke things without prior warning;
as far as I can tell, its breakages were all in areas that C90
had *not* described as obsolescent. Maybe a C1x that limited
itself to breaking things described as obsolescent in C99 would
get a friendlier reception. Or maybe not.

--
Eric Sosman
eso...@ieee-dot-org.invalid

BGB / cr88192

unread,
Nov 18, 2009, 1:12:40 AM11/18/09
to

"Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
news:7mh98oF...@mid.individual.net...

> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
> news:hdv5ri$49d$1...@news.albasani.net...
>>
>> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
>> news:7mgbo7F...@mid.individual.net...
>>> "Flash Gordon" <sm...@spam.causeway.com> wrote in message
>>> news:0c7bt6x...@news.flash-gordon.me.uk...
>>>> I think it is about time to remove some of the things which were
>>>> deprecated in 1989 at least. I agree with the poster who suggested
>>>> making an empty parameter list mean no parameters (void) rather than an
>>>> unspecified number of parameters.
>>>
>>> I think it would be wiser to do it in two steps -- make it a syntax
>>> error first, and then re-introduce it with the new meaning in the next
>>> version of the standard. This would give compilers a few years of
>>> freedom to choose whether to support the old semantics or the new as an
>>> extension.
>>>
>>
>> I disagree...
>>
>> since, as I see it, "()" has 2 meanings at the same time:
>> "()" as an empty list (implicit, but common);
>
> Do you mean common outside of C, or commonly misinterpreted in C?
>

it is "implicitly valid" as a grace of what it does mean:
a function can be declared with "()";
a function can be called with "()";
the compliler does what is expected.


>> "()" as an arbitrary number (official, but uncommon).
>
> I remember it being fairly common. Before ANSI C it was the only way to
> declare a fuction in C.
>

not now.
anymore, if a person types "()", almost invariably they mean an empty list.


>> there is a very large amount of code which uses the former definition,
>> but
>
> Again, in C??? Or in C++, Java, etc?
>

in C...

one does not have to look far and wide to find it, it is infact far more
common in the code I have seen than the use of "(void)".


>> almost no code I have seen which (intentionally) uses the latter
>> (although, programmers may sometimes stumble across it on accident, and
>> then end up assuming it to be some kind of compiler bug...).
>
> What do you call people who actually understand the tools that they're
> using? "Professional programmers", as opposed to just "programmers"? ;-)
>

programmers are programmers, some know some of this trivia, some don't know
but this does not hinder them from "getting the job done", some know and
don't care, ...


>> the former case is implicitly contained in the latter, where the former
>> is the common understanding and usage, and the latter is what is
>> officially in the standard.
>
> Well my experience of what is "common" seems to differ from yours.
>

probably, may depend some on which code and which communities one is exposed
to.

checking around in random code from random projects, it seems it is not as
clear-cut as I had thought:
I encountered several projects using '(void)', some using '()', and a few
using K&R style declarations (actually, I had seen code alternative between
K&R and more modern style as well).

I guess I was slightly off, as it does appear for pure C codebases (and not
mixed C and C++ codebases), '(void)' would seem to hold a majority position,
but both styles would seem to be in use in general.

>> so, FWIW, it would be more a matter of deprecating a "bug" than of
>> introducing (conceptually) new semantics.
>
> Apparently my definition of "bug" differs from yours as well.
>

it may resemble a bug, if it happens unexpectedly, granted it is not
technically a bug as such.


>> if compilers were to make "()" a syntax error, OTOH, a rather large
>> amount of code would break, so much so that likely almost no compiler
>> project/vendor would likely consider doing so (it is worth noting that
>> the general adoption of the "(void)" convention has been rather sparse
>> IME, and personally I don't feel it to be the right direction either,
>> ...).
>
> I didn't say that compilers would have to reject "()" as a syntax error;
> on the contrary, I did talk about letting them interpret "()" either the
> old way or the new way, as an extension. Just like compilers can still
> support implicit int even though it was removed in C99. A lot of
> extensions look like syntax errors to the standard; many of them (like
> "long long" or "for (int i=0;;)") become part of another version of the
> standard.
>

yes, ok.


my compiler interprets "()" as an empty list, as well as failing to parse
implicit int or K&R style syntax. among other issues, it is not strictly
standards-conformant, but it works well enough for my uses at present
(granted, "making it ready for prime time" would probably require a bit of
fixing up in the edge cases...).

sadly, my projects as a whole have gotten larger than I can really manage
effectively, and so it is difficult to prevent "rust", and often bugs are
not fixed unless I start beating head-first into them.

(doesn't help here that I am the only developer here...).

sadly, resolving this issue would probably require cutting off a lot of code
and persuing more agressive "anti-bloat" practices, but even this would
require a lot of time and effort resources.

for now though, it all just continues as-is...


it is not all bad though, as it helps give one a better perspective on "the
industry" in general, and helps one learn how to utilize their coding
efforts a little more efficiently (getting bigger effects with less code,
such as how to get by with generalizing or re-purposing existing code and
facilities to support new tasks, rather than always writing new code, ...).

but, alas, still much more new code ends up written, ... so, really, I don't
know what the eventual outcome of all this will be.

Dag-Erling Smørgrav

unread,
Nov 18, 2009, 5:56:42 AM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> writes:
> since, as I see it, "()" has 2 meanings at the same time:
> "()" as an empty list (implicit, but common);
> "()" as an arbitrary number (official, but uncommon).
>
> there is a very large amount of code which uses the former definition, but
> almost no code I have seen which (intentionally) uses the latter (although,
> programmers may sometimes stumble across it on accident, and then end up
> assuming it to be some kind of compiler bug...).

Three arguments in favor:

1) I believe most C programmers expect () to mean "no arguments"; just
look at how many programmers (not to mention how many programming
texts) use main() instead of main(void).

2) There is no use for the "any number of arguments" semantics if
K&R-style function definitions are removed from the language.

3) () already means (void) in C++.

Dag-Erling Smørgrav

unread,
Nov 18, 2009, 6:06:44 AM11/18/09
to
"Wojtek Lerch" <wojt...@yahoo.ca> writes:
> "BGB / cr88192" <cr8...@hotmail.com> writes:
> > since, as I see it, "()" has 2 meanings at the same time:
> > "()" as an empty list (implicit, but common);
> Do you mean common outside of C, or commonly misinterpreted in C?

Common in C, since () is an empty argument list in a function *call*
even if it isn't in a function *declaration*.

Giacomo Catenazzi

unread,
Nov 18, 2009, 9:14:31 AM11/18/09
to
Dag-Erling Smørgrav wrote:
> 1) I believe most C programmers expect () to mean "no arguments"; just
> look at how many programmers (not to mention how many programming
> texts) use main() instead of main(void).

really?

The main uses of main is:
int main (int argc, char *argv[]);

thus I expect for many C programmes main() means: any number of
arguments but I don't care about arguments.

BTW many implementation allows also a third argument in main
(but this is discouraged by POSIX):
" Implementations are required to support the two-argument calling
sequence, but this does not prohibit an implementation from supporting
envp as an optional third argument. "

ciao
cate

Wojtek Lerch

unread,
Nov 18, 2009, 10:57:18 AM11/18/09
to
"Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
news:he0017$s10$1...@news.eternal-september.org...

> Perhaps I have misunderstood your suggestion, which I read
> as proposing two changes in two successive Standards. C1x would
> outlaw a construct that is well-defined (albeit "obsolescent")
> in C90 and C99, then C2x would give the abandoned construct a
> new meaning different from that it now has. C2x would be an
> "extension" from the viewpoint of C1x, but both C1x and C2x would
> be "incompatible changes" from the standpoint of C90 and C99.

Yes, that's what I proposed, as an alternative to making both changes at
once in C1X. Personally, I don't have strong feelings against keeping the
old K&R syntax in C1X, only against keeping a little chunk of it with
changed semantics and outlawing the rest. (Presumably, the original
proposal intended to make "int foo();" legal and equivalent to "int
foo(void);", but to make "void foo(x) int x; {}" a syntax error, correct?)

> Also, I reiterate my skepticism about the power of the
> Standard to "forbid" things. A Standard that breaks existing
> correct code will meet resistance, even if the breakage arises
> from good intentions; consider the C99 experience. Of course,
> it should be noted that C99 broke things without prior warning;
> as far as I can tell, its breakages were all in areas that C90
> had *not* described as obsolescent. Maybe a C1x that limited
> itself to breaking things described as obsolescent in C99 would
> get a friendlier reception. Or maybe not.

I'm sure breaking programs that use gets() would get a much friendlier
reception from some people around here than breaking programs using the K&R
syntax would.

Wojtek Lerch

unread,
Nov 18, 2009, 11:00:10 AM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:he038o$co4$1...@news.albasani.net...

> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
> news:7mh98oF...@mid.individual.net...
>> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
>> news:hdv5ri$49d$1...@news.albasani.net...
...

>>> "()" as an arbitrary number (official, but uncommon).
>>
>> I remember it being fairly common. Before ANSI C it was the only way to
>> declare a fuction in C.
>
> not now.

No, but some old code has a nasty habit of sticking around for a long time.
Remember Y2K?

If C1X were to outlaw the old K&R syntax, outlawing all of it would make all
that old code generate clear error messages with a C1X-conforming compiler.
If C1X accepted "()" with the new semantics instead, some of the error
messages you'd get from the old code would likely be much less helpful.
(Think about code that uses function pointers.)

> anymore, if a person types "()", almost invariably they mean an empty
> list.

Since I don't recall using the "()" syntax, or seeing it used by any of the
competent programmers I am fortunate to work with, in quite a few years, I
guess I don't have any evidence to disprove your "if". ;-)

...


> checking around in random code from random projects, it seems it is not as
> clear-cut as I had thought:
> I encountered several projects using '(void)', some using '()', and a few
> using K&R style declarations (actually, I had seen code alternative
> between K&R and more modern style as well).

Well, are you still in favour if banning the K&R style and, just to confuse
the people still using it, accepting "()" as a synonym of "(void)"?


Wojtek Lerch

unread,
Nov 18, 2009, 11:00:23 AM11/18/09
to
"Dag-Erling Smørgrav" <d...@des.no> wrote in message
news:868we4w...@ds4.des.no...

Obviously, the discussion wasn't about outlawing "()" in function calls.

BGB / cr88192

unread,
Nov 18, 2009, 12:17:16 PM11/18/09
to

"Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
news:7mik0bF...@mid.individual.net...

> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
> news:he038o$co4$1...@news.albasani.net...
>> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
>> news:7mh98oF...@mid.individual.net...
>>> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
>>> news:hdv5ri$49d$1...@news.albasani.net...
> ...
>>>> "()" as an arbitrary number (official, but uncommon).
>>>
>>> I remember it being fairly common. Before ANSI C it was the only way to
>>> declare a fuction in C.
>>
>> not now.
>
> No, but some old code has a nasty habit of sticking around for a long
> time. Remember Y2K?
>

from what I have seen, it is rare bits and pieces of code "here and there",
but is a fairly strong minority (granted, it would imply people going and
fixing lots of older codebases if this were to be done).

it could be made an "optional" feature, as in, a compiler is not in
violation if it implements it (say, for legacy code support), but a compiler
which has no real need to be used with legacy code need not bother to
support it.


> If C1X were to outlaw the old K&R syntax, outlawing all of it would make
> all that old code generate clear error messages with a C1X-conforming
> compiler. If C1X accepted "()" with the new semantics instead, some of the
> error messages you'd get from the old code would likely be much less
> helpful. (Think about code that uses function pointers.)
>

potentially...

however, also possible is that it be left up to the implementation:
some could warn that a particular use case is deprecated;
others could report syntax errors (due to not having bothered to implement
said syntax).

the latter case would likely be more common in special-purpose compilers.


>> anymore, if a person types "()", almost invariably they mean an empty
>> list.
>
> Since I don't recall using the "()" syntax, or seeing it used by any of
> the competent programmers I am fortunate to work with, in quite a few
> years, I guess I don't have any evidence to disprove your "if". ;-)
>

it depends on project and community...

I have encountered places where this convention is used, for example, in the
Windows Platform SDK, ..., and a few places where "(void)" is used (mostly
in "gl/gl.h").

then again, it could be debated that the Platform SDK is a mixed-language
codebase (having lots of C++ here and there as well), and so does not count,
...


> ...
>> checking around in random code from random projects, it seems it is not
>> as clear-cut as I had thought:
>> I encountered several projects using '(void)', some using '()', and a few
>> using K&R style declarations (actually, I had seen code alternative
>> between K&R and more modern style as well).
>
> Well, are you still in favour if banning the K&R style and, just to
> confuse the people still using it, accepting "()" as a synonym of
> "(void)"?
>

generally, yes, however this would likely only be needed for "new"
compilers, since older compliers likely have good reason to retain support
for legacy code.

anyways, since "()" has this meaning in C++ / Java / C# / ... it makes sense
to keep this meaning, rather than going and making C be "the odd man out" by
insisting on "(void)" for empty args lists...


>


Keith Thompson

unread,
Nov 18, 2009, 12:36:33 PM11/18/09
to

Obviously.

But if you ignore previous C practice, using "()" to mean no
parameters in a declaration and no arguments in a call just
makes more sense than having the special-case "(void)" syntax.
The only reason for "(void)" to mean zero parameters, or for "()"
to mean anything other than zero parameters, is for compatibility
with old code. If we were designing a new language, I don't think
we'd even consider having a special case.

Alas, we have to do this in the real world, and we have to trade off
the cleanliness of having "()" mean what it looks like, vs. the risk
of breaking old code.

Also, we can't remove "(void)" from the language; that would break way
too much existing code, including code that was specifically written
to conform to the C90 or C99 standard. So even if we completely
drop old-style declarations and make "()" mean zero parameters,
we'll be stuck with two ways of writing the same thing.

BGB / cr88192

unread,
Nov 18, 2009, 1:21:11 PM11/18/09
to

"Keith Thompson" <ks...@mib.org> wrote in message
news:lny6m3y...@nuthaus.mib.org...
> "Wojtek Lerch" <wojt...@yahoo.ca> writes:
>> "Dag-Erling Sm�rgrav" <d...@des.no> wrote in message

>> news:868we4w...@ds4.des.no...
>>> "Wojtek Lerch" <wojt...@yahoo.ca> writes:
>>>> "BGB / cr88192" <cr8...@hotmail.com> writes:
>>>> > since, as I see it, "()" has 2 meanings at the same time:
>>>> > "()" as an empty list (implicit, but common);
>>>> Do you mean common outside of C, or commonly misinterpreted in C?
>>>
>>> Common in C, since () is an empty argument list in a function *call*
>>> even if it isn't in a function *declaration*.
>>
>> Obviously, the discussion wasn't about outlawing "()" in function calls.
>
> Obviously.
>
> But if you ignore previous C practice, using "()" to mean no
> parameters in a declaration and no arguments in a call just
> makes more sense than having the special-case "(void)" syntax.
> The only reason for "(void)" to mean zero parameters, or for "()"
> to mean anything other than zero parameters, is for compatibility
> with old code. If we were designing a new language, I don't think
> we'd even consider having a special case.
>

agreed.


> Alas, we have to do this in the real world, and we have to trade off
> the cleanliness of having "()" mean what it looks like, vs. the risk
> of breaking old code.
>

agreed, but removing K&R in the first place would risk breaking code, and
leaving in "()" even with modified semantics would still break far less code
than removing it outright...

it could be defined as defining zero arguments, but with an implementation,
at its discretion, optionally allowing multiple arguments.


> Also, we can't remove "(void)" from the language; that would break way
> too much existing code, including code that was specifically written
> to conform to the C90 or C99 standard. So even if we completely
> drop old-style declarations and make "()" mean zero parameters,
> we'll be stuck with two ways of writing the same thing.
>

granted...

then again, there are multiple ways of doing lots of things, so IMO this is
not such a bad tradeoff...

Wojtek Lerch

unread,
Nov 18, 2009, 1:31:34 PM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:he1a6t$8qn$1...@news.albasani.net...

> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
> news:7mik0bF...@mid.individual.net...

>> No, but some old code has a nasty habit of sticking around for a long

>> time. Remember Y2K?
>
> from what I have seen, it is rare bits and pieces of code "here and
> there", but is a fairly strong minority (granted, it would imply people
> going and fixing lots of older codebases if this were to be done).

Precisely. And I'm sure a decent portion of that older codebase is not
actively maintained but does get recompiled from time to time. If that code
breaks, all of a sudden you have to find (and pay!!!) someone that will be
able to understand it and make it compile again.

> it could be made an "optional" feature, as in, a compiler is not in
> violation if it implements it (say, for legacy code support), but a
> compiler which has no real need to be used with legacy code need not
> bother to support it.

How exactly does that differ from what I called an "extension"?

>> If C1X were to outlaw the old K&R syntax, outlawing all of it would make
>> all that old code generate clear error messages with a C1X-conforming
>> compiler. If C1X accepted "()" with the new semantics instead, some of
>> the error messages you'd get from the old code would likely be much less
>> helpful. (Think about code that uses function pointers.)
>
> potentially...
>
> however, also possible is that it be left up to the implementation:
> some could warn that a particular use case is deprecated;
> others could report syntax errors (due to not having bothered to implement
> said syntax).

It's either deprecated (i.e. valid for now) or a syntax error (i.e. not
valid) -- it can't be both at the same time.

But if the standard considers it a syntax error, that does not forbid
compilers to still support it as an extension-- as long as a diagnostic is
produced ("Warning: K&R style is no longer standard C"), a compiler is free
to accept the code. Supporting extensions is up to the implementation.

>> ...


>>> I encountered several projects using '(void)', some using '()', and a
>>> few using K&R style declarations (actually, I had seen code alternative
>>> between K&R and more modern style as well).
>>
>> Well, are you still in favour if banning the K&R style and, just to
>> confuse the people still using it, accepting "()" as a synonym of
>> "(void)"?
>
> generally, yes, however this would likely only be needed for "new"
> compilers, since older compliers likely have good reason to retain support
> for legacy code.

Which category do new versions of old compilers belong to? I'd say that
they likely have good reson to retain support for any code that their older
version supported. Are you suggesting that the new C standard should only
require support for the new meaning of "()" from brand-new compilers written
from scratch as version 1.0? Don't you think it would be silly for a
language standard to make that kind of a distinction between "old" compilers
and "new" compilers?

> anyways, since "()" has this meaning in C++ / Java / C# / ... it makes
> sense to keep this meaning, rather than going and making C be "the odd man
> out" by insisting on "(void)" for empty args lists...

Personally I think it's more important for C to stay consistent with C than
to become consistent with C++, Java, or C#. Besides, C was there first --
it was those other languages that decided to become inconsistent with C, not
the other way around.


BGB / cr88192

unread,
Nov 18, 2009, 2:46:24 PM11/18/09
to

"Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
news:7miss7F...@mid.individual.net...

> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
> news:he1a6t$8qn$1...@news.albasani.net...
>> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
>> news:7mik0bF...@mid.individual.net...
>
>>> No, but some old code has a nasty habit of sticking around for a long
>>> time. Remember Y2K?
>>
>> from what I have seen, it is rare bits and pieces of code "here and
>> there", but is a fairly strong minority (granted, it would imply people
>> going and fixing lots of older codebases if this were to be done).
>
> Precisely. And I'm sure a decent portion of that older codebase is not
> actively maintained but does get recompiled from time to time. If that
> code breaks, all of a sudden you have to find (and pay!!!) someone that
> will be able to understand it and make it compile again.
>

yep.


>> it could be made an "optional" feature, as in, a compiler is not in
>> violation if it implements it (say, for legacy code support), but a
>> compiler which has no real need to be used with legacy code need not
>> bother to support it.
>
> How exactly does that differ from what I called an "extension"?
>

"extension" usually implies something specific to an implementation, which
may be done however the implementation sees fit;
optional features are left at the discretion of an implementation, but if
implemented, than the means of doing so are well defined (have X or not have
X).

by analogy:
a CPU may or may not have SSE5, either way is valid (SSE5 is optional);
however, having something different which fulfills the same role is not the
same, this is an extension IMO...

granted, I am not normally fond of this level of pedantics...


>>> If C1X were to outlaw the old K&R syntax, outlawing all of it would make
>>> all that old code generate clear error messages with a C1X-conforming
>>> compiler. If C1X accepted "()" with the new semantics instead, some of
>>> the error messages you'd get from the old code would likely be much less
>>> helpful. (Think about code that uses function pointers.)
>>
>> potentially...
>>
>> however, also possible is that it be left up to the implementation:
>> some could warn that a particular use case is deprecated;
>> others could report syntax errors (due to not having bothered to
>> implement said syntax).
>
> It's either deprecated (i.e. valid for now) or a syntax error (i.e. not
> valid) -- it can't be both at the same time.
>
> But if the standard considers it a syntax error, that does not forbid
> compilers to still support it as an extension-- as long as a diagnostic is
> produced ("Warning: K&R style is no longer standard C"), a compiler is
> free to accept the code. Supporting extensions is up to the
> implementation.
>

yes, ok.


>>> ...
>>>> I encountered several projects using '(void)', some using '()', and a
>>>> few using K&R style declarations (actually, I had seen code alternative
>>>> between K&R and more modern style as well).
>>>
>>> Well, are you still in favour if banning the K&R style and, just to
>>> confuse the people still using it, accepting "()" as a synonym of
>>> "(void)"?
>>
>> generally, yes, however this would likely only be needed for "new"
>> compilers, since older compliers likely have good reason to retain
>> support for legacy code.
>
> Which category do new versions of old compilers belong to? I'd say that
> they likely have good reson to retain support for any code that their
> older version supported. Are you suggesting that the new C standard
> should only require support for the new meaning of "()" from brand-new
> compilers written from scratch as version 1.0? Don't you think it would
> be silly for a language standard to make that kind of a distinction
> between "old" compilers and "new" compilers?
>

well, it is not inherent in the compilers, but it is a property of the
process of writing code.
for an older compiler, the choice is likely already set: "why should we
remove something, if doing so will break some existing code?";
for a newer compiler, the situation is different: "why should I bother
adding support for something no one will likely use?".

granted, these sorts of distinctions would not make much sense to be stated
in the standards...


>> anyways, since "()" has this meaning in C++ / Java / C# / ... it makes
>> sense to keep this meaning, rather than going and making C be "the odd
>> man out" by insisting on "(void)" for empty args lists...
>
> Personally I think it's more important for C to stay consistent with C
> than to become consistent with C++, Java, or C#. Besides, C was there
> first -- it was those other languages that decided to become inconsistent
> with C, not the other way around.
>

it also makes little sense for it to diverge further than it was already,
since "()" has been valid all along, but making it invalid would be a
change.

so, it is not so much about C following along with other languages, but
rather, it not needlessly diverging...

>


Wojtek Lerch

unread,
Nov 18, 2009, 2:49:26 PM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:he1duo$f0k$1...@news.albasani.net...

> "Keith Thompson" <ks...@mib.org> wrote in message
> news:lny6m3y...@nuthaus.mib.org...
>> Alas, we have to do this in the real world, and we have to trade off
>> the cleanliness of having "()" mean what it looks like, vs. the risk
>> of breaking old code.
>
> agreed, but removing K&R in the first place would risk breaking code, and
> leaving in "()" even with modified semantics would still break far less
> code than removing it outright...

Maybe a little less, but not "far less"; and the breakage would be less
trivial to fix.

Completely removing the old K&R syntax would simply break all K&R-style
declarations and definitions, and produce error messages pointing directly
at them.

Allowing "()" for functions that don't have parameters would let all
function declarations, as well as definitions of functions taking no
arguments, be accepted; but then any call to a function that was declared
with the "()" but called with arguments would be flagged as incorrect,
likely pointing you at the line number where the function is called but not
where it was declared. This would increase the amount of work to find and
fix functions that do take arguments, which, in my experience, constitute a
vast majority of all C functions.

Keith Thompson

unread,
Nov 18, 2009, 2:51:34 PM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> writes:
> "Keith Thompson" <ks...@mib.org> wrote in message
> news:lny6m3y...@nuthaus.mib.org...
[...]

>> Alas, we have to do this in the real world, and we have to trade off
>> the cleanliness of having "()" mean what it looks like, vs. the risk
>> of breaking old code.
>
> agreed, but removing K&R in the first place would risk breaking code, and
> leaving in "()" even with modified semantics would still break far less code
> than removing it outright...
>
> it could be defined as defining zero arguments, but with an implementation,
> at its discretion, optionally allowing multiple arguments.

There's no need for the standard to grant this specific permission.
Implementations are always free to provide extensions in conforming
mode, or to provide a non-conforming mode that does whatever the
implementer likes.

For example, if this:

void foo();

meant that foo has no parameters, then this:

foo(42);

would be a constraint violation. A conforming implementation could
still accept it with a warning, and a non-conforming implementation
(which could be just a command-line option to an otherwise conforming
implementation) could accept it without a warning.

C99 dropped implicit int. It's not optional, it's just gone from
the language. In practice, that hasn't actually broken the existing
programs that depend on it. The same thing would happen if C201X
dropped old-style function declarations.

Optional features make the language more complex. That can be
worthwhile in some cases, but I don't think it is here.

[...]

Wojtek Lerch

unread,
Nov 18, 2009, 4:09:37 PM11/18/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:he1iug$n46$1...@news.albasani.net...

> "Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
> news:7miss7F...@mid.individual.net...
>> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
>> news:he1a6t$8qn$1...@news.albasani.net...

>>> it could be made an "optional" feature, as in, a compiler is not in

>>> violation if it implements it (say, for legacy code support), but a
>>> compiler which has no real need to be used with legacy code need not
>>> bother to support it.
>>
>> How exactly does that differ from what I called an "extension"?
>
> "extension" usually implies something specific to an implementation, which
> may be done however the implementation sees fit;
> optional features are left at the discretion of an implementation, but if
> implemented, than the means of doing so are well defined (have X or not
> have X).

OK, so the new standard could say that it's implementation-defined whether
an empty list in a function declaration constitutes a prototype for a
function that has no parameters, or an old K&R-style function type that
contains no information about the parameters. That means that it would need
to keep the existing distinction between the old K&R-style function types
versus function types declared with a prototype, and the complicated rules
of compatibility between the two styles of function types, and the behaviour
of the function call operator depending on which style of a function type
designates the function being called; and it could just drop the actual K&R
declaration and definition syntax. And all the kept text would need to be
reviewed and rewritten to ensure that it's not trying to refer to the
removed syntax.

Personally, I have the feeling that the committee is not willing to spend
the time trying to re-write the semantics of K&R function types just for the
sake of redefining the old behaviour and making it optional. I would expect
it to be much simpler to just remove any traces of the old function types
from the standard for good, and simply say that all function types involve a
prototype. Then, a separate decision could be made about whether to remove
the "()" from the syntax or to treat it as equivalent to "(void)", and
whether to do that right away or just mention the plan in a non-normative
appendix for now. My experience is that the committee is not going to waste
any sleep over the possibility that letting implementations make their own
decisions about the meaning of "()" as an extension can, in theory, result
in implementations maliciously inventing really strange semantics for it.

>>> anyways, since "()" has this meaning in C++ / Java / C# / ... it makes
>>> sense to keep this meaning, rather than going and making C be "the odd
>>> man out" by insisting on "(void)" for empty args lists...
>>
>> Personally I think it's more important for C to stay consistent with C
>> than to become consistent with C++, Java, or C#. Besides, C was there
>> first -- it was those other languages that decided to become
>> inconsistent with C, not the other way around.
>
> it also makes little sense for it to diverge further than it was already,
> since "()" has been valid all along, but making it invalid would be a
> change.

The difference is that making it invalid, along with all other K&R-style
declarations, would be a small and natural part of a bigger and change.
Making it valid with different semantics would make it unnecessarily
difficult to weed out any remaining traces of the obsolescent K&R-style
declarations from legacy code, for the sake of pleasing incompetent
programmers who do not understand the difference between the deprecated "()"
and the correct "(void)" in C today.

Eric Sosman

unread,
Nov 18, 2009, 5:06:37 PM11/18/09
to
Wojtek Lerch wrote:
> "Eric Sosman" <eso...@ieee-dot-org.invalid> wrote
>> [...] A Standard that breaks existing

>> correct code will meet resistance, even if the breakage arises
>> from good intentions; [...]

>
> I'm sure breaking programs that use gets() would get a much friendlier
> reception from some people around here than breaking programs using the
> K&R syntax would.

Yes. But code that calls gets() is already broken, so
there'd be no change in the status of any existing program.

(All right, "any" may overstate the case. But not by
much; you can probably count the valid gets() uses without
taking your shoes off. Even Captain Hook could likely do so.)

--
Eric Sosman
eso...@ieee-dot-org.invalid

Wojtek Lerch

unread,
Nov 18, 2009, 10:16:07 PM11/18/09
to
"Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
news:he1r5f$unk$1...@news.eternal-september.org...

> Wojtek Lerch wrote:
>> I'm sure breaking programs that use gets() would get a much friendlier
>> reception from some people around here than breaking programs using the
>> K&R syntax would.
>
> Yes. But code that calls gets() is already broken, so
> there'd be no change in the status of any existing program.

I don't know what your exact definition of "broken" is; my favourite one, I
think, is based on the actual behaviour of a program not matching its
required (expected, claimed, or documented) behaviour. To me, there's a big
difference between "does not compile" and "dies from a SIGSEGV for some
invalid inputs", especially for programs that are not intended to be run in
a hostile environment and are not required to be paranoid about invalid
inputs.

(Personally I tend to write code that does more validation than necessary,
especially when little is really necessary, and I never use gets(). But
somehow its existence does not bother me. I've seen a fair amount of code
that could be steered into undefined behaviour by invalid inputs, and as far
as I can remember none of it used gets().)

BGB / cr88192

unread,
Nov 18, 2009, 10:28:31 PM11/18/09
to

"Wojtek Lerch" <wojt...@yahoo.ca> wrote in message
news:7mjrjoF...@mid.individual.net...

maybe it likes to gets() into the troubles...

James Kuyper

unread,
Nov 19, 2009, 7:17:48 AM11/19/09
to
Wojtek Lerch wrote:
> "Eric Sosman" <eso...@ieee-dot-org.invalid> wrote in message
> news:he1r5f$unk$1...@news.eternal-september.org...
>> Wojtek Lerch wrote:
>>> I'm sure breaking programs that use gets() would get a much
>>> friendlier reception from some people around here than breaking
>>> programs using the K&R syntax would.
>>
>> Yes. But code that calls gets() is already broken, so
>> there'd be no change in the status of any existing program.
>
> I don't know what your exact definition of "broken" is; my favourite
> one, I think, is based on the actual behaviour of a program not matching
> its required (expected, claimed, or documented) behaviour.

In this context, I would consider a program to be broken if the behavior
required by the relevant standards for the source code does not match
the intended behavior of the program; in particular, if the behavior is
undefined, it cannot match, except by accident.

"Relevant standards" is meant to take into consideration the targeted
platforms - not all code needs to be maximally portable. If the targets
are exclusively POSIX platforms, it's OK to rely upon POSIX for the
definition of the behavior; if the targets are exclusively ones for
which a particular version of a particular compiler is available, it's
OK to rely upon documented features of that compiler.

Both in principle, and in practice on virtually every implementation I'm
aware of, the behavior of gets() can be undefined if unexpected input is
provided. Therefore a program that uses it is broken unless stdin is
tightly controlled; such control cannot be achieved using exclusively
standard C features within the same program as the gets() call. It might
be controllable within the same program by using OS-specific features
that give control over stdin; it can easily be controlled by having
something outside of the program ensure that the input to the program
using gets() is safe.

However, I think that the frequency with which gets() is actually being
used safely is far smaller than the frequency with which people are
using gets() in the mistaken belief that it is safe.


> To me,
> there's a big difference between "does not compile" and "dies from a

> SIGSEGV for some invalid inputs", ...

If you could guarantee the SIGSEGV, that wouldn't be so bad. However, it
often can result in overwriting some other piece of memory being used
for some other purpose, with highly unpredictable results. It could have
consequences much worse than "dies immediately", and I'm not just
talking about theoretical nasal demons here, but actual plausible outcomes.

Wojtek Lerch

unread,
Nov 19, 2009, 10:06:26 AM11/19/09
to
"James Kuyper" <james...@verizon.net> wrote in message
news:he3d1c$38n$1...@news.eternal-september.org...
> Wojtek Lerch wrote:
...

>> I don't know what your exact definition of "broken" is; my favourite one,
>> I think, is based on the actual behaviour of a program not matching its
>> required (expected, claimed, or documented) behaviour.
>
> In this context, I would consider a program to be broken if the behavior
> required by the relevant standards for the source code does not match the
> intended behavior of the program; in particular, if the behavior is
> undefined, it cannot match, except by accident.

If the behaviour is undefined in circumstances in which the program was not
intended to be run, and therefore no particular behaviour was specified or
expected or forbidden, in my book that does not make the program "broken".
I doubt a lot of programs are so completely bullet-proof that they can't
possibly ever run into undefined behaviour if something really unexpected
happens. How do you ensure that your program can't possibly run out of
stack? How many programs check if an external process isn't modifying their
files under their feet? Or, worse, their variables in memory?

How much time can you afford to spend writing code that checks for all those
practically impossible theoretical possibilities, compared to the useful
code that will actually be executed? Does the answer not depend on how the
program is intended to be used -- personally there's a big difference
between how I treat a program intended to be executed with elevated
privileges on behalf of untrusted users, compared to a simple test program
that I'm quickly putting together just to run it once myself and then throw
away.

...


> However, I think that the frequency with which gets() is actually being
> used safely is far smaller than the frequency with which people are using
> gets() in the mistaken belief that it is safe.

That's possible; I have not seen enough uses of gets() to consider it
meaningful evidence of anything other than a low importance of the gets()
problem. But I suspect that the kind of people who mistakenly believe that
using gets() is safe make a lot of other, more serious mistakes in their
code, and removing gets() from the standard, or even from their code, is not
going to make a big improvement.

>> To me, there's a big difference between "does not compile" and "dies
>> from a SIGSEGV for some invalid inputs", ...
>
> If you could guarantee the SIGSEGV, that wouldn't be so bad. However, it
> often can result in overwriting some other piece of memory being used for
> some other purpose, with highly unpredictable results. It could have
> consequences much worse than "dies immediately", and I'm not just talking
> about theoretical nasal demons here, but actual plausible outcomes.

In practice, it's a matter of probabilities. On many implementations,
feeding a long line to gets() results in overwriting the return address on
the stack and, unless the input was carefully crafted, a jump to a random
location. On a lot of systems, the address represented by a buffer of
printable characters is so large that you'll never find anything other than
empty space there, and indeed an immediate SIGSEGV is pretty much
guaranteed. If the practical chance of something harmful happening seems
lower than the chance of accidentally deleting all my files by dropping a
coffee cup on my keyboard, often I won't bother writing much code to avoid
it. Especially if I have backup copies of my files anyway.

James Kuyper

unread,
Nov 20, 2009, 7:37:15 AM11/20/09
to
Wojtek Lerch wrote:
> "James Kuyper" <james...@verizon.net> wrote in message
> news:he3d1c$38n$1...@news.eternal-september.org...
>> Wojtek Lerch wrote:
> ...
>>> I don't know what your exact definition of "broken" is; my favourite
>>> one, I think, is based on the actual behaviour of a program not
>>> matching its required (expected, claimed, or documented) behaviour.
>>
>> In this context, I would consider a program to be broken if the
>> behavior required by the relevant standards for the source code does
>> not match the intended behavior of the program; in particular, if the
>> behavior is undefined, it cannot match, except by accident.
>
> If the behaviour is undefined in circumstances in which the program was
> not intended to be run, and therefore no particular behaviour was
> specified or expected or forbidden, in my book that does not make the
> program "broken".

I covered that issue with my use of the phrase "relevant standards", and
included a long explanation that I was using the term "standard" is a
loose sense, that would include implementation-specific documentation of
any feature that the program relied upon, so long as it was only to be
used on implementations providing that feature.


> ... I doubt a lot of programs are so completely

> bullet-proof that they can't possibly ever run into undefined behaviour
> if something really unexpected happens. How do you ensure that your
> program can't possibly run out of stack? How many programs check if an
> external process isn't modifying their files under their feet? Or,
> worse, their variables in memory?

That falls under the more general rule: what you can't do anything
about, you shouldn't waste time worrying about - though I wouldn't
certainly be interested in a language, or at least a language feature,
which provided some method of anticipate and cope with running out of stack.

Is anyone familiar with such a feature, either in a variation of C, or
in some other language? If so, how is it used by the developer, and is
it even remotely feasible to standardize a similar feature as part of
some future version of C? A signal that's thrown after the stack runs
out doesn't quite handle the job; there should be some way to undo
what's been done, and possible resume operations using an alternative
algorithm that requires less memory.

...


>>> To me, there's a big difference between "does not compile" and "dies
>>> from a SIGSEGV for some invalid inputs", ...
>>
>> If you could guarantee the SIGSEGV, that wouldn't be so bad. However,
>> it often can result in overwriting some other piece of memory being
>> used for some other purpose, with highly unpredictable results. It
>> could have consequences much worse than "dies immediately", and I'm
>> not just talking about theoretical nasal demons here, but actual
>> plausible outcomes.
>
> In practice, it's a matter of probabilities. On many implementations,
> feeding a long line to gets() results in overwriting the return address
> on the stack and, unless the input was carefully crafted, a jump to a
> random location. On a lot of systems, the address represented by a
> buffer of printable characters is so large that you'll never find
> anything other than empty space there, and indeed an immediate SIGSEGV
> is pretty much guaranteed.

I've seen much more bizarre consequences from writing past the end of a
buffer than the ones you've described, and I've seen them often enough
to be far more worried about the "unlikely" possibilities than you seem
to be.

Wojtek Lerch

unread,
Nov 20, 2009, 10:37:27 AM11/20/09
to
"James Kuyper" <james...@verizon.net> wrote in message
news:he62hs$8cj$1...@news.eternal-september.org...
> Wojtek Lerch wrote:
>> ...

>> If the behaviour is undefined in circumstances in which the program was
>> not intended to be run, and therefore no particular behaviour was
>> specified or expected or forbidden, in my book that does not make the
>> program "broken".
>
> I covered that issue with my use of the phrase "relevant standards", and
> included a long explanation that I was using the term "standard" is a
> loose sense, that would include implementation-specific documentation of
> any feature that the program relied upon, so long as it was only to be
> used on implementations providing that feature.

No, that's a different issue. I wasn't talking about "relevant
standards" -- I was talking about the stated requirements for the particular
program. If they specifically say that the program shall not be run with
input whose lines exceed 80 bytes, or in an environment where external
processes may be modifying its files, then regardless of what the program's
behaviour is when those conditions are violated, even it's undefined by the
"relevant standards", it does not make the program "broken".

Just to make it clear, I'm not saying that adding some code to avoid
undefined behaviour is a bad idea and a waste of time. Just because a
program isn't "broken" according to my definition, that doesn't mean it's a
good program. Good programs tend to exceed their stated requirements, not
just meet them. The quality of code is not a Boolean -- code can be
"excellent", "good", "adequate", or "broken"; or anything in between.

>> ... I doubt a lot of programs are so completely bullet-proof that they
>> can't possibly ever run into undefined behaviour if something really
>> unexpected happens. How do you ensure that your program can't possibly
>> run out of stack? How many programs check if an external process isn't
>> modifying their files under their feet? Or, worse, their variables in
>> memory?
>
> That falls under the more general rule: what you can't do anything about,
> you shouldn't waste time worrying about - though I wouldn't certainly be
> interested in a language, or at least a language feature, which provided
> some method of anticipate and cope with running out of stack.

But if invalid input makes one program run out of stack and another program
overflow a buffer, would you say that the second program is "broken" but the
first one is not? Would be it just because none of the "relevant standards"
provided a way for the first program to avoid running out of stack?

What if *valid* input makes a program run out of stack -- would you not
consider that program "broken"?

> ...


> I've seen much more bizarre consequences from writing past the end of a
> buffer than the ones you've described, and I've seen them often enough to
> be far more worried about the "unlikely" possibilities than you seem to
> be.

It's all a matter of balance between how likely something bad can happen and
how bad can it possibly be. During development and debugging, ocassionally
running into undefined behaviour is hard to avoid. If there's a small
chance that undefined behaviour can damage my hard drive, making sure that I
have backup copies of all my files may be a reasonable way of living with
that risk. If I'm writing a program that I intend to only run myself, then
letting that program invoke undefined behaviour for invalid inputs may also
be reasonable -- especially if I'll only run the program while debugging
other programs, and the risk of undefined behaviour of this program is
likely to be negligible compared to undefined behaviour of the program being
debugged.

On the other hand, telling a customer (or, worse, not telling him) that
invalid input can make my program damage his hard drive, just because the
requirements he specified did not mention anything about invalid inputs,
would be much less acceptable than spending some extra time adding code to
try to be reasonably sure that the program doesn't run into undefined
behaviour. But if there are things that can't possibly be avoided (like
stack overflow), or things that would take an unreasonable amount of work to
avoid (like other processes messing with your files), then letting them
happen does not necessarily make the program "broken".

Francis Glassborow

unread,
Nov 20, 2009, 11:31:16 AM11/20/09
to


Yes, a program that behaves correctly when used according to its
specifications is not broken even if it fails when provided with
incorrect data. However, if the program is safety (or even just mission
critical) it should deal adequately with all input that it could
conceivably have. Otherwise it is not fit for purpose.

Wojtek Lerch

unread,
Nov 20, 2009, 11:59:37 AM11/20/09
to
"Francis Glassborow" <francis.g...@btinternet.com> wrote in message
news:67CdnXm4f-PFWZvW...@bt.com...
> Wojtek Lerch wrote:
>> ... I was talking about the stated requirements for the particular
>> program. If they specifically say that the program shall not be run with
>> input whose lines exceed 80 bytes, or in an environment where external
>> processes may be modifying its files, then regardless of what the
>> program's behaviour is when those conditions are violated, even it's
>> undefined by the "relevant standards", it does not make the program
>> "broken".
>
> Yes, a program that behaves correctly when used according to its
> specifications is not broken even if it fails when provided with incorrect
> data. However, if the program is safety (or even just mission critical) it
> should deal adequately with all input that it could conceivably have.
> Otherwise it is not fit for purpose.

Sure; but if the program is safety- or mission-critical, then its documented
requirements should describe how it's supposed to react to invalid inputs.
If they don't, then it's the requirements that are broken, not the program.

jameskuyper

unread,
Nov 23, 2009, 4:12:09 PM11/23/09
to
Wojtek Lerch wrote:
> "James Kuyper" <james...@verizon.net> wrote in message
> news:he62hs$8cj$1...@news.eternal-september.org...
> > Wojtek Lerch wrote:
> >> ...
> >> If the behaviour is undefined in circumstances in which the program was
> >> not intended to be run, and therefore no particular behaviour was
> >> specified or expected or forbidden, in my book that does not make the
> >> program "broken".
> >
> > I covered that issue with my use of the phrase "relevant standards", and
> > included a long explanation that I was using the term "standard" is a
> > loose sense, that would include implementation-specific documentation of
> > any feature that the program relied upon, so long as it was only to be
> > used on implementations providing that feature.
>
> No, that's a different issue. I wasn't talking about "relevant
> standards" -- I was talking about the stated requirements for the particular
> program. If they specifically say that the program shall not be run with
> input whose lines exceed 80 bytes, or in an environment where external
> processes may be modifying its files, then regardless of what the program's
> behaviour is when those conditions are violated, even it's undefined by the
> "relevant standards", it does not make the program "broken".

That issue was already covered by a different part of my original
statement "does not match the intended behavior. If "corrupts the
database" is within the range of behavior that is intended to be
allowed if the pre-conditions of a program are not met, then there's
nothing wrong with the program having precisely that behavior under
those circumstances.

I personally have a problem imagining any circumstance under which I
would intend that a program have arbitrarily bad behavior just because
it's been misused; but my statement is sufficiently flexible to cover
that possibility.

Wojtek Lerch

unread,
Nov 23, 2009, 10:25:26 PM11/23/09
to
"jameskuyper" <james...@verizon.net> wrote in message
news:9a5234d9-f996-46b0...@h10g2000vbm.googlegroups.com...

> Wojtek Lerch wrote:
>> "James Kuyper" <james...@verizon.net> wrote in message
>> news:he62hs$8cj$1...@news.eternal-september.org...
>> > Wojtek Lerch wrote:
>> >> ...
>> >> If the behaviour is undefined in circumstances in which the program
>> >> was
>> >> not intended to be run, and therefore no particular behaviour was
>> >> specified or expected or forbidden, in my book that does not make the
>> >> program "broken".
>> >
>> > I covered that issue with my use of the phrase "relevant standards",
>> > [...]

>>
>> No, that's a different issue. I wasn't talking about "relevant
>> standards" -- I was talking about the stated requirements for the
>> particular
>> program. [...]

>
> That issue was already covered by a different part of my original
> statement "does not match the intended behavior.

But in that part you said, "in particular, if the behavior is undefined, it
cannot match, except by accident", which sounded to me like you meant that a
program that exhibits undefined behaviour cannot possibly match the intended
behaviour, no matter what the intended behaviour is, including (I assumed)
when the intended behaviour is completely unrestricted because the
pre-conditions aren't met. But it seems now that I must have misunderstuud,
and that we don't really disagree.

> If "corrupts the
> database" is within the range of behavior that is intended to be
> allowed if the pre-conditions of a program are not met, then there's
> nothing wrong with the program having precisely that behavior under
> those circumstances.

Right. And if no restrictions whatsoever are intended for the behaviour
when the pre-conditions are met, then undefined behaviour is acceptable too.

> I personally have a problem imagining any circumstance under which I
> would intend that a program have arbitrarily bad behavior just because
> it's been misused; but my statement is sufficiently flexible to cover
> that possibility.

A similar reasoning could be applied to library functions: why would you
agree to have a library function that invokes undefined behaviour when
misused? The answer is, of course, that for some reason you may prefer to
make it the responsibility of the user to ensure that the function isn't
misused. Similarly, if a program is a part of a bigger system, the design
of the system can make it the responsibility of other parts of the system to
ensure that the program is not misused. In the case of my little test
programs, the "other parts" of the bigger system is me. :)

jameskuyper

unread,
Nov 24, 2009, 2:47:03 AM11/24/09
to
I'm accessing the internet under rather tight time restrictions right
now, and didn't finish answering the following message during my last
session.

Wojtek Lerch wrote:
> "James Kuyper" <james...@verizon.net> wrote in message
> news:he62hs$8cj$1...@news.eternal-september.org...
> > Wojtek Lerch wrote:
...

> >> ... I doubt a lot of programs are so completely bullet-proof that they
> >> can't possibly ever run into undefined behaviour if something really
> >> unexpected happens. How do you ensure that your program can't possibly
> >> run out of stack? How many programs check if an external process isn't
> >> modifying their files under their feet? Or, worse, their variables in
> >> memory?
> >
> > That falls under the more general rule: what you can't do anything about,
> > you shouldn't waste time worrying about - though I wouldn't certainly be
> > interested in a language, or at least a language feature, which provided
> > some method of anticipate and cope with running out of stack.
>
> But if invalid input makes one program run out of stack and another program
> overflow a buffer, would you say that the second program is "broken" but the
> first one is not? Would be it just because none of the "relevant standards"
> provided a way for the first program to avoid running out of stack?

Buffer overflow can often be avoided or even completely prevented with
sufficiently careful programming; running out of stack generally
cannot be. I don't bother about the latter until it bites me, then I
figure out how to make my program require less stack. The former I
deal with proactively with defensive programming techniques, and I
would consider a program broken if it produced unintended behavior by
reason of failing to use such techniques.

> What if *valid* input makes a program run out of stack -- would you not
> consider that program "broken"?

If the program that runs out of stack was not intended to have the
resulting behavior on a machine with the amount of stack memory that
was actually available, is broken. Otherwise, it is not.

jameskuyper

unread,
Nov 24, 2009, 2:59:09 AM11/24/09
to

Actually, my comment about "cannot match" reflects the fact that I
hadn't considered the possibility that someone would be willing to
include the full, horrific range of possibilities available with
"undefined behavior" as "intended behavior", just because a program
has been misused.

I am personally a strong advocate of graceful failure; the idea that
even when misused, a program should try to detect the misuse before it
would otherwise undefined behavior, and deals with the misuse in a way
that causes as little additional damage as possible - which is
absolutely inconsistent with allowing the undefined behavior occur. It
should also provide the investigator with at least some useful clues
as to how the program had been misused. However, my comment about
"intended result" was intended to cover the possibility that the
program was developed by someone who didn't share my preference for
graceful failure.

Wojtek Lerch

unread,
Nov 24, 2009, 11:09:41 AM11/24/09
to
"jameskuyper" <james...@verizon.net> wrote in message
news:11581b90-43dd-4f28...@j11g2000vbi.googlegroups.com...

> Actually, my comment about "cannot match" reflects the fact that I
> hadn't considered the possibility that someone would be willing to
> include the full, horrific range of possibilities available with
> "undefined behavior" as "intended behavior", just because a program
> has been misused.

But in most practical cases, the range is not "horrific" and completely
unrestricted! In most cases, the result of faulty hardware can be just as
bad or worse, and most of us have learned to accept the fact that hardware
sometimes fails. Fortunately, very few computer systems have the capacity
to detonate a nuclear bomb or shut down a continental power grid, and I
imagine that most of them have hardware safeguards to minimize the risk of
those things happening unintentionally as a result of undefined behaviour in
a program. Most common implementations try to ensure that any harmful
results of undefined behaviour are contained within the process that
misbehaved, or if that fails, at least that they don't have a way to affect
other users. If you misuse a program by mistake and it destroys all your
files, at least you know who to blame (either yourself or the programmer,
depending on whether the possibility was documented clearly enough). If a
hardware failure causes the same result, blame is not as easy to place.

Some programs can destroy all your files, or produce other horrific results,
*without* invoking undefined behaviour. Some programs are *designed* to
remove files or format disks, and often it's actually easier to cause harm
by misusing them than by misusing programs that have undefined behaviour.
In the real world, you can't possibly assume that it's impossible to cause
harm by misusing a program unless the program is "broken".

> I am personally a strong advocate of graceful failure; the idea that
> even when misused, a program should try to detect the misuse before it
> would otherwise undefined behavior, and deals with the misuse in a way
> that causes as little additional damage as possible - which is
> absolutely inconsistent with allowing the undefined behavior occur. It

I agree, as long as we keep the word "try" in there. But what if the
program tries and fails? Sometimes there may be possibilities (such as
running out of stack, or other programs modifying your data under your feet)
that are unreasonably expensive or maybe even impossible to detect inside a
C program, and in those cases you may have no choice but to move the
responsibility of preventing them somewhere outside of the program.
Especially if they are very easy to prevent outside of the program.

jameskuyper

unread,
Nov 25, 2009, 3:53:53 AM11/25/09
to
Wojtek Lerch wrote:
> "jameskuyper" <james...@verizon.net> wrote in message
> news:11581b90-43dd-4f28...@j11g2000vbi.googlegroups.com...
...

> > I am personally a strong advocate of graceful failure; the idea that
> > even when misused, a program should try to detect the misuse before it
> > would otherwise undefined behavior, and deals with the misuse in a way
> > that causes as little additional damage as possible - which is
> > absolutely inconsistent with allowing the undefined behavior occur. It
>
> I agree, as long as we keep the word "try" in there. But what if the
> program tries and fails? Sometimes there may be possibilities (such as
> running out of stack, or other programs modifying your data under your feet)
> that are unreasonably expensive or maybe even impossible to detect inside a
> C program, and in those cases you may have no choice but to move the
> responsibility of preventing them somewhere outside of the program.

If you've done everything that can reasonably be done, to avoid
undefined behavior, then of course you're not at fault for not doing
the things that you can't do. It was never my intention to impose a
requirement to do the impossible.

Thad Smith

unread,
Nov 28, 2009, 7:20:43 PM11/28/09
to
Keith Thompson wrote:
> Are there any thoughts of removing any other obsolescent or deprecated
> features?
...
> The placement of a storage-class specifier other than at the
> beginning of the declaration specifiers in a declaration

My coding style is to declare the function return type on a separate
line along with a comment:

int /* number of qubers found */
static findQubers (
const char *in /* source to search for qubers */
) {
...
}

Static here refers to the function, not the return type. It makes
sense, to me, to place static on the line with the function name.

--
Thad

0 new messages