Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > some well known stupidness in c99

Reply
Thread Tools

some well known stupidness in c99

 
 
Rui Maciel
Guest
Posts: n/a
 
      11-18-2012
fir wrote:

>> Is there any reason why none of the C alternatives described above would
>> be acceptable for use in your program?
>>

>
> #define is not acceptable by me I dislike
> using preprocessor and use only few includes
> (do not like it either) and nothing more of it


It sounds like you don't do any work with C or C++.


Rui Maciel
 
Reply With Quote
 
 
 
 
Rui Maciel
Guest
Posts: n/a
 
      11-18-2012
fir wrote:

> defines are not such stupid but preprocesor
> can be consideren not as part of c but

<snip/>

The C preprocessor is C. It is defined in the C standard. It can't be more
C than that.


Rui Maciel
 
Reply With Quote
 
 
 
 
Joachim Schmitz
Guest
Posts: n/a
 
      11-18-2012
fir wrote:
<snip>
> When I wrote some messages on this group
> (not many times that was my third visit here)
> really I often met a ppl which I see try to make 'much effort to not
> understand me'
> (Really, I see suc thing here)
>
> It would be hard to explain such basic
> things why
>
> coinst int table_max = 4096;
>
> is better than
>
> enum { table_max = 4096 }


How can one syntax error be better than another?
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-18-2012
fir <(E-Mail Removed)> writes:
> It is sad to say so but there is some real and terrible stupidnes in
> c99. When i wrote programs in c (and I am involved c user) I just use
> const int for array boundaries but in c99 (and some previous too,
> terribly) it will not compile (see for example
> http://stackoverflow.com/questions/1...-at-file-scope
> ) It is terribly wrong thing for ppl who just wants to use const int
> to this purposes and not to use preprocesor - as I do. It is terribly
> stupidness in my opinion, it have to be changed.


C is not, never has been, and never will be a 100% cleanly designed
language. Its own creator, Dennis Ritchie, wrote that "C is quirky,
flawed, and a tremendous success."

It has evolved over decades from earlier versions, and from earlier
languages (B, BCPL), and most updates to the language have carefully
maintained (mostly) backward compatibility, to avoid breaking existing
code.

Personally, I agree that it would be nice if C treated const definitions
with constant initializers the way C++ does, so that given

const int answer = 42;

answer would be a constant expression, and I would support such a
change in a future revision. Kenneth Brody pointed out a case where
such a change could break existing code:

===== file1.c

const int table_max = 100;

===== file2.c

extern const int table_max;

This could probably be worked around by making the definition introduce
a constant expression *and* a read-only object. Or, I suppose, the
commitee could decide that it's ok to break existing code in this case,
though that's probably unlikely.

But such a change would require some significant work to define its
behavior in *all* cases, followed by changes to all conforming C
implementations.

I suspect the committee would hesitate to make such a change when there
are already ways to do this, namely:

#define table_max 100 /* should probably be TABLE_MAX */

and

enum { table_max = 100 };

(The latter has the drawback that it works only for constants of
type int.)

I know you've said that you dislike the preprocessor, but you can't
reasonably expect the committee to reject a solution that's been
in common use for decades, and that works perfectly well, because
some guy named "fir" doesn't like it (no offense intended).

Major revisions of the C standard have been issued in 1989/1990,
1999, and 2011. Assuming that new revisions are produced on a
similar schedule, we can expect a new one in 2021 or so. The best
case scenario for the change you advocate is that the committee
spends time between now and 2021 nailing down its definition,
followed by at least several years before implementers fully support
the new standard. You'll then be able to use the new feature --
but only if your code doesn't need to be compiled with pre-C2021
compilers.

So you can either spend the next decade complaining that C's lack
of this feature is "stupid", or you can grit your teeth and use an
enum or #define.

Incidentally, posting in comp.lang.c that this is "stupid"
is definitely not the best way to get this change to happen.
comp.std.c, which discusses the C standard (as opposed to the
langauge defined by that standard) would be better, but even it
has no official standing with the committee, though a few members
do hang out there. (Check the group's history before posting;
it's likely that this idea has been proposed there before.)

And telling the committee that their work is "terribly stupidness"
will not get you anywhere.

And please either use something other than Google Groups to post here,
or clean up the double-spacing it imposes on quoted text before clicking
"send".

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-18-2012
On 11/18/2012 3:52 PM, fir wrote:
> [...]
> It would be hard to explain such basic
> things why
>
> coinst int table_max = 4096;
>
> is better than
>
> enum { table_max = 4096 }


C's enum is not of much use, I'll agree: It's only an int
with lipstick, plus just enough mystery to be alluring before
one gets to know it better. I wouldn't recommend enum as a
substitute for the kind of "coinst" you desire, even if it can
sometimes be put to that use.

But where's the case that `#define table_max 4096' is
inferior to "coinst"? So far, the *only* reason that's been
put forward is "fir doesn't like it." Somehow, "I don't like
it, therefore it's stupid" doesn't sound like the sort of
proof Euclid would be proud of.

> (this reason is not purely aesthetic but i
> meant that giving up with const ints here
> and go intu enums would be terrible aesthetic
> failure for me) Seem terribly obvious for me,
> and not seeing it end using enums here seem
> to be very stupid for me
>
> defines are not such stupid but preprocesor
> can be consideren not as part of c but some
> external tool to use over it (it was initialy
> considered like that, check out c history note)
> and i also treat it such way (as external tool
> over c, with not to much use for me personally)


In the very earliest days of C, the preprocessor was in
truth a separate entity. It didn't exist until about 1972-3,
and for a while the early compilers didn't even run it on
source files that didn't appear to use it. But its integration
into the language did not take long: by 1978 we find K&R saying
"The C compiler *contains* [emphasis mine] a preprocessor" (p. 207),
not "Hey, there's this extra tool you can use if you like."

If you've been doing the arithmetic, you'll see that the
preprocessor is at most forty years old and that C's inventor
considered it as contained in the compiler as of at least
thirty-four years ago. Since the preprocessor has been part
of the language for at least eighty-five percent of its entire
existence, the assertion that it should be thought of as "some
external tool" cannot be taken seriously.

The preprocessor is a full-fledged part of the language,
and provides the solution to your problem. Just use it!

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      11-18-2012
On 11/18/2012 03:22 PM, BartC wrote:
> "Kenneth Brody" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed). ..

....
>> I find it highly unlikely that this fart of the language will change,
>> considering the fact that you can have:
>>
>> ===== file1.c
>>
>> const int table_max = 100;
>>
>> ===== file2.c
>>
>> extern const int table_max;
>>
>> .... references to "table_max" that cannot be a compile-time constant ...

>
> Why not? I can do this in another language


Because, at compile time for file2.c, file1.c is not visible, and the
value of table_max cannot be known. Any language that allows you to do
this does not support true separate compilation.

> In any case, the language ought to provide true named constants, which are
> pretty fundamental, not expect everyone to mess around with enums, defines,
> and const attributes. Then the above won't be a problem.


Object-like macros have a name, and can expand into constant
expressions. Enumeration constants have a name and a constant value. In
what way do either them fail to qualify as "true named constants"?
You'll need to add at least one additional adjective to the phrase
"named constants" to justify rejecting them.
--
James Kuyper
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-18-2012
"fir" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> W dniu niedziela, 18 listopada 2012 21:10:33 UTC+1 u┼╝ytkownik Eric Sosman
> napisał:


>
>> In short, "stupidity" is "whatever offends fir's delicate
>>
>> aesthetic sensibilities."


> It would be hard to explain such basic
> things why
>
> coinst int table_max = 4096;
>
> is better than
>
> enum { table_max = 4096 }


I can see exactly why the use of enum doesn't seem satisfactory (being
designed for a different purpose, for a start).

But neither is 'const int' much better, defining an int *variable* not a
value, which by some luck happens to be usable as a compile-time value.

For some inexplicable reason, the designers of C could find no use for a
construct such as:

constant int abc = 8192;
constant double xyz = 60.7796;

whose values are *guaranteed* to be always what they say, where the names
obey normal scoping rules, and which was part of plenty of other languages.

However if you are offended by such things as enums and defines, then
there's a lot worse in the language!

C is pretty ancient and is not going to change dramatically any time soon.

--
Bartc

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      11-18-2012
fir <(E-Mail Removed)> writes:
[...]
> When I wrote some messages on this group (not many times that was my
> third visit here) really I often met a ppl which I see try to make
> 'much effort to not understand me' (Really, I see suc thing here)
>
> It would be hard to explain such basic things why
>
> coinst int table_max = 4096;
>
> is better than
>
> enum { table_max = 4096 }
>
> (this reason is not purely aesthetic but i meant that giving up with
> const ints here and go intu enums would be terrible aesthetic failure
> for me) Seem terribly obvious for me, and not seeing it end using
> enums here seem to be very stupid for me


In my opinion, the difference *is* purely esthetic (apart from the
fact that the "const" version doesn't work in C).

I guess that English is not your first language, so perhaps you're
not aware that the word "stupid" is quite insulting. I suggest
not using it in a technical discussion like this. (No offense;
your English is certainly better than my own nonexistent Polish.)

Despite the similarity of the words "const" and "constant",
they're really not the same thing in C. A "constant expression"
is, roughly, an expression that can be evaluated at compile time,
and that can be used where you'd use a literal constant like 42.
(I say "roughly" because the language defines which expressions
are to be treated as constant expressions; there are expressions
that a particular compiler *can* evaluate at compile time that
don't qualify. It's necessary to have a consistent definition for
all compilers; the set of constant expressions doesn't expand as
compilers become more clever.)

The keyword "const", on the other hand, really means "read-only";
it means that an object's value may not be modified after it's been
created and initialized. For example, this:

const time_t now = time(NULL);
srand(now);
const int r = rand();

is perfectly valid, even though the compiler cannot possibly
determine the values of "now" and "r" before the program executes.
It just means that, for example, "r++" is not allowed.

C++ has added a special-case rule, that if an object is declared
"const" (read-only), and its initialization is a constant expression,
then the object's name can be used as a constant expression.
(I'm probably not stating the rule *quite* correctly, but that's
close enough.)

> defines are not such stupid but preprocesor can be consideren not as
> part of c but some external tool to use over it (it was initialy
> considered like that, check out c history note) and i also treat it
> such way (as external tool over c, with not to much use for me
> personally)


Any program that uses any header (<stdio.h>, <stdlib.h>, etc.) must
use the preprocessor. The preprocessor is absolutely part of the
language; it's defined that way by the ISO C standard. You can't
avoid it. If you dislike the preprocessor that much, perhaps you'd
prefer some other language.

[...]

You'd like C to permit the name of a const-defined object as a
constant expression, as C does. I think most of us agree with you.
But the plain fact is that C doesn't support that, and it's not
going to any time soon.

You have two and only two options:
1. Use C.
2. Don't use C.

Make your choice and move on.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      11-18-2012


"James Kuyper" <(E-Mail Removed)> wrote in message
news:k8bm1u$rqm$(E-Mail Removed)...
> On 11/18/2012 03:22 PM, BartC wrote:
>> "Kenneth Brody" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed). ..


>>> ===== file1.c
>>>
>>> const int table_max = 100;
>>>
>>> ===== file2.c
>>>
>>> extern const int table_max;
>>>
>>> .... references to "table_max" that cannot be a compile-time constant
>>> ...

>>
>> Why not? I can do this in another language

>
> Because, at compile time for file2.c, file1.c is not visible, and the
> value of table_max cannot be known. Any language that allows you to do
> this does not support true separate compilation.


Well, OK, in the language I had in mind, it would be tricky to do mutual
imports and exports (file1 importing names from file2, and vice versa). But
just to do the above example, it would look like this:

In file1:

global const table_max = 100

And in file2:

import file1

which makes available 'table_max' as a compile-time constant.

It does require that file1 is compiled (or somehow processed) first. After
that, the source does not need to be visible to file2 (what's important is
the exports file created for file1, which is what is processed by the
'import' statement, but this is little different to the common header file
that C might use, if 'table_max' is to be accessed from several other
modules).

It's also possible to write:

global const table_max = a + b + c.len # a bit like sizeof(c)

where a, b and c are locals, but only table_max is exported.

This sort of stuff is fiddly to do in C. Apparently you can't even export
the size of a local array as a compile-time constant (according to a recent
thread). And most global names seem to need to be defined twice: a shared
declaration, and a definition. It seems weak on importing and exporting
(imo).


>> In any case, the language ought to provide true named constants, which
>> are
>> pretty fundamental, not expect everyone to mess around with enums,
>> defines,
>> and const attributes. Then the above won't be a problem.

>
> Object-like macros have a name, and can expand into constant
> expressions. Enumeration constants have a name and a constant value. In
> what way do either them fail to qualify as "true named constants"?
> You'll need to add at least one additional adjective to the phrase
> "named constants" to justify rejecting them.


In another post in this thread, I gave the example of a proposed 'constant'
attribute which illustrates what I had in mind for a 'true named constant'.
This does exactly what is intended, without going around the houses trying
to achieve the same with whatever else C has lying around.

Actually I can't see why something so simple is not part of the language
anyway, *even if* the same thing can be achieved in several other indirect
ways.

The problem with named macros is mainly that of scope. Also, while you can
have a macro ABC that expands to the literal '73128', it could also expand
to '73)+*('!

There are one or two other things, for example a macro defined as a complex
100-term expression, used in 100 places in the code, could mean parsing
10000 tokens and evaluating the expression 100 times. A dedicated 'constant
feature would evaluate the expression once, and would occupy 100 tokens in
the code.

The problem with enums I think is more of 'type' (only available for int).
Also you always get the impression they were created for a specific purpose
(related sets of constants), and it seems like you're hijacking the feature
when you use it just because 'constant' isn't available.

--
Bartc

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      11-18-2012
On 11/18/2012 5:45 PM, BartC wrote:
>
>
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:k8bm1u$rqm$(E-Mail Removed)...
>> On 11/18/2012 03:22 PM, BartC wrote:
>>> "Kenneth Brody" <(E-Mail Removed)> wrote in message
>>> news:(E-Mail Removed). ..

>
>>>> ===== file1.c
>>>>
>>>> const int table_max = 100;
>>>>
>>>> ===== file2.c
>>>>
>>>> extern const int table_max;
>>>>
>>>> .... references to "table_max" that cannot be a compile-time constant
>>>> ...
>>>
>>> Why not? I can do this in another language

>>
>> Because, at compile time for file2.c, file1.c is not visible, and the
>> value of table_max cannot be known. Any language that allows you to do
>> this does not support true separate compilation.

>
> Well, OK, in the language I had in mind, it would be tricky to do mutual
> imports and exports (file1 importing names from file2, and vice versa). But
> just to do the above example, it would look like this:
>[...]


You've missed James' point. Try this example:

/* file1.c */
const int table_max = 100;

/* file2.c */
const int table_max = 200;

/* victim.c */
extern const int table_max;
int table[table_max];

From these three files I want to make two programs: One
that links file1.o+victim.o, the other using file2.o+victim.o.
Explain how table_max is a compile-time constant in victim.

Also, I just wrote file1.c and file2.c today, but I wrote
and compiled victim.c->victim.o a month ago. Again, explain
how table_max was a compile-time constant a month before I
decided on any of the values it might someday have.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Is this phase-accumulator trick well-known??? Mike Treseler VHDL 0 02-08-2009 07:17 PM
List mutation method gotcha - How well known? Hendrik van Rooyen Python 20 03-16-2008 09:55 AM
Difference between "library parts" of C99 and "language parts" of C99 albert.neu@gmail.com C Programming 3 03-31-2007 08:14 PM
C99 struct initialization (C99/gcc) jilerner@yahoo.com C Programming 3 02-20-2006 04:41 AM
well-known Internet sites which use Java based web servers Mladen Adamovic Java 3 10-24-2005 09:48 PM



Advertisments