Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #21713 > unrolled thread
| Started by | Les Cargill <lcargill99@comcast.com> |
|---|---|
| First post | 2012-06-02 15:43 -0500 |
| Last post | 2012-06-08 20:30 -0700 |
| Articles | 20 on this page of 51 — 14 participants |
Back to article view | Back to comp.lang.c
Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-02 15:43 -0500
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-03 08:56 +1200
Re: Array sizes and const Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 16:59 -0400
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-02 16:35 -0500
Re: Array sizes and const jgk@panix.com (Joe keane) - 2012-06-08 20:05 +0000
Re: Array sizes and const jgk@panix.com (Joe keane) - 2012-06-09 21:36 +0000
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-02 16:43 -0500
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-02 14:59 -0700
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-02 17:12 -0500
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-02 18:27 -0700
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-02 22:27 -0500
Re: Array sizes and const "BartC" <bc@freeuk.com> - 2012-06-03 11:24 +0100
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-03 13:51 -0700
Re: Array sizes and const "BartC" <bc@freeuk.com> - 2012-06-04 12:20 +0100
Re: Array sizes and const Jens Gustedt <jens.gustedt@loria.fr> - 2012-06-04 13:54 +0200
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-04 14:32 -0700
Re: Array sizes and const Nobody <nobody@nowhere.com> - 2012-06-02 23:50 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-03 10:53 +1200
Re: Array sizes and const Nobody <nobody@nowhere.com> - 2012-06-03 14:35 +0100
Re: Array sizes and const James Kuyper <jameskuyper@verizon.net> - 2012-06-02 21:11 -0400
Re: Array sizes and const Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 07:39 -0700
Re: Array sizes and const James Kuyper <jameskuyper@verizon.net> - 2012-06-03 16:03 -0400
Re: Array sizes and const Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-03 21:49 +0100
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-03 14:49 -0700
Re: Array sizes and const Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 15:02 -0700
Re: Array sizes and const Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-04 01:21 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 09:08 +1200
Re: Array sizes and const Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 15:08 -0700
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 10:37 +1200
Re: Array sizes and const "BartC" <bc@freeuk.com> - 2012-06-03 23:47 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 10:55 +1200
Re: Array sizes and const Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 16:04 -0700
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 11:14 +1200
Re: Array sizes and const "BartC" <bc@freeuk.com> - 2012-06-04 00:23 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 11:30 +1200
Re: Array sizes and const "BartC" <bc@freeuk.com> - 2012-06-04 00:52 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 12:04 +1200
Re: Array sizes and const Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-04 01:39 +0100
Re: Array sizes and const Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-04 02:35 -0700
Re: Array sizes and const Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-04 01:33 +0100
Re: Array sizes and const Ian Collins <ian-news@hotmail.com> - 2012-06-04 12:35 +1200
Re: Array sizes and const pacman@kosh.dhis.org (Alan Curry) - 2012-06-04 21:28 +0000
Re: Array sizes and const James Kuyper <jameskuyper@verizon.net> - 2012-06-04 12:08 -0400
Re: Array sizes and const jgk@panix.com (Joe keane) - 2012-06-04 22:49 +0000
Re: Array sizes and const David Brown <david.brown@hesbynett.no> - 2012-06-03 15:46 -0500
Re: Array sizes and const Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 02:08 -0700
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-08 06:45 -0500
Re: Array sizes and const Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 10:49 -0700
Re: Array sizes and const Les Cargill <lcargill99@comcast.com> - 2012-06-08 18:05 -0500
Re: Array sizes and const Keith Thompson <kst-u@mib.org> - 2012-06-08 13:31 -0700
Re: Array sizes and const Tim Rentsch <txr@alumni.caltech.edu> - 2012-06-08 20:30 -0700
Page 1 of 3 [1] 2 3 Next page →
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-06-02 15:43 -0500 |
| Subject | Array sizes and const |
| Message-ID | <jqdtou$koe$1@dont-email.me> |
I am using Mingw 3.4.5 on a 'Doze box, but it pretty much follows any Gnu compiler I've run into. Why is this: --------------------------- #define SIZE 20 const int size = SIZE; char array[SIZE]; --------------------------- legal, yet --------------------------- #define SIZE 20 const int size = SIZE; char array[size]; --------------------------- not? The int size is invariant, and ... "morally" equivalent to using SIZE, yet it won't let me do that. And yes, I understand/speak/grok preprocessor vs. compiler. I know *how*, I just wonder *why*. Is this a practical, strategic or tactical thing, or am I just being silly? Was it a conscious decision of the committee, or just one of those things? Thanks in a advance for any consideration. -- Les Cargill
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-06-03 08:56 +1200 |
| Message-ID | <a2vcvuF47cU3@mid.individual.net> |
| In reply to | #21713 |
On 06/ 3/12 08:43 AM, Les Cargill wrote: > > I am using Mingw 3.4.5 on a 'Doze box, but it pretty much > follows any Gnu compiler I've run into. > > Why is this: > > --------------------------- > #define SIZE 20 > const int size = SIZE; > char array[SIZE]; > --------------------------- > > legal, yet > > --------------------------- > #define SIZE 20 > const int size = SIZE; > char array[size]; > --------------------------- > > not? Because const is broken in C. > The int size is invariant, and ... "morally" > equivalent to using SIZE, yet it won't let me do that. > > And yes, I understand/speak/grok preprocessor vs. > compiler. I know *how*, I just wonder *why*. Is > this a practical, strategic or tactical thing, > or am I just being silly? Was it a conscious decision > of the committee, or just one of those things? My guess would be an oversight in the original standard. It's unfortunate that two opportunities to correct it have now been missed. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-02 16:59 -0400 |
| Message-ID | <jqdur3$qu0$1@dont-email.me> |
| In reply to | #21713 |
On 6/2/2012 4:43 PM, Les Cargill wrote:
>
> I am using Mingw 3.4.5 on a 'Doze box, but it pretty much
> follows any Gnu compiler I've run into.
>
> Why is this:
>
> ---------------------------
> #define SIZE 20
> const int size = SIZE;
> char array[SIZE];
> ---------------------------
>
> legal, yet
>
> ---------------------------
> #define SIZE 20
> const int size = SIZE;
> char array[size];
> ---------------------------
>
> not?
>
> The int size is invariant, and ... "morally"
> equivalent to using SIZE, yet it won't let me do that.
>
> And yes, I understand/speak/grok preprocessor vs.
> compiler. I know *how*, I just wonder *why*. Is
> this a practical, strategic or tactical thing,
> or am I just being silly? Was it a conscious decision
> of the committee, or just one of those things?
`const' doesn't mean "constant." Roughly speaking, it means
"unwritable" -- and even that's not quite true, because a
`const volatile' object might be writable by something outside C
itself (a hardware timer, for example, might be read-only to the
C program but writeable by a little silicon doodad).
With that in mind, back to your question. In `char array[SIZE];'
the macro is replaced by the token `20', and that token represents
an integer literal, something that is in fact constant. But in
`char array[size];', `size' is a variable that will acquire some
value when the program is eventually executed. In this case it is
easy to see what the (initial) value will be, but nonetheless: It's
a variable, not a constant.
Just for added fun (or confusion), the "C99" version of the C
Standard added a rule to the language that allows for a "variable-
length array" whose dimension is computed at run-time rather than
at compile time. Taken as a VLA, `char array[size];' is perfectly
legal: It's an array with `size' elements (whatever `size' happens
to be at the moment), and which gets memory allocated to it when the
declaration is reached. However, file-scope arrays (and `static'
arrays inside functions) get their memory before the program even
starts, so their dimensions must be known prior to execution. A
VLA must have `auto' storage, meaning that it can only exist inside
a function.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-06-02 16:35 -0500 |
| Message-ID | <jqe0qg$758$1@dont-email.me> |
| In reply to | #21715 |
Eric Sosman wrote: > On 6/2/2012 4:43 PM, Les Cargill wrote: >> >> I am using Mingw 3.4.5 on a 'Doze box, but it pretty much >> follows any Gnu compiler I've run into. >> >> Why is this: >> >> --------------------------- >> #define SIZE 20 >> const int size = SIZE; >> char array[SIZE]; >> --------------------------- >> >> legal, yet >> >> --------------------------- >> #define SIZE 20 >> const int size = SIZE; >> char array[size]; >> --------------------------- >> >> not? >> >> The int size is invariant, and ... "morally" >> equivalent to using SIZE, yet it won't let me do that. >> >> And yes, I understand/speak/grok preprocessor vs. >> compiler. I know *how*, I just wonder *why*. Is >> this a practical, strategic or tactical thing, >> or am I just being silly? Was it a conscious decision >> of the committee, or just one of those things? > > `const' doesn't mean "constant." Agreed - and that's probably the most important thing I'm "missing" here. Ah, the const keyword... Even after all these years, I *really* want it to mean that... > Roughly speaking, it means > "unwritable" -- and even that's not quite true, because a > `const volatile' object might be writable by something outside C > itself (a hardware timer, for example, might be read-only to the > C program but writeable by a little silicon doodad). > Sure. "Not writable by this program". And when I must mix const and volatile, I still end up reading about it... What we usually want is a const pointer to a volatile object. But not always - for things like... DMA controllers ( in kernel mode ) we may express pointers in hardware registers... so it may be a const pointer to a volatile *pointer*. I did a quick Google, and it seems to be a serious point of confusion. A thing to translate all the permutations of const/static/volatile to English would be very handy... The examples seem to avoid pointer syntax, which is unfortunate. > With that in mind, back to your question. In `char array[SIZE];' > the macro is replaced by the token `20', and that token represents > an integer literal, something that is in fact constant. Yessir. > But in > `char array[size];', `size' is a variable that will acquire some > value when the program is eventually executed. In this case it is > easy to see what the (initial) value will be, but nonetheless: It's > a variable, not a constant. > And a declaration cannot depend on a variable, whether it is invariant or not... > Just for added fun (or confusion), the "C99" version of the C > Standard added a rule to the language that allows for a "variable- > length array" whose dimension is computed at run-time rather than > at compile time. Taken as a VLA, `char array[size];' is perfectly > legal: It's an array with `size' elements (whatever `size' happens > to be at the moment), and which gets memory allocated to it when the > declaration is reached. However, file-scope arrays (and `static' > arrays inside functions) get their memory before the program even > starts, so their dimensions must be known prior to execution. A > VLA must have `auto' storage, meaning that it can only exist inside > a function. > -- Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-06-08 20:05 +0000 |
| Message-ID | <jqtltr$bn9$1@reader1.panix.com> |
| In reply to | #21718 |
In article <jqe0qg$758$1@dont-email.me>, Les Cargill <lcargill99@comcast.com> wrote: >Even after all these years, I *really* want it to mean that... Pascal (but it had this insane thing of requiring you to put them in a certain order, and it didn't have header files so it is moot)
[toc] | [prev] | [next] | [standalone]
| From | jgk@panix.com (Joe keane) |
|---|---|
| Date | 2012-06-09 21:36 +0000 |
| Message-ID | <jr0fkt$ep6$1@reader1.panix.com> |
| In reply to | #21718 |
In article <jqe0qg$758$1@dont-email.me>, Les Cargill <lcargill99@comcast.com> wrote: >Agreed - and that's probably the most important thing I'm "missing" >here. CPP is a bit... inelegant but so far as #define BAR_INIT_NUM_STICKS 10 even #define BAR_IS_RED(BAR) (((BAR)->bar_fl & 0x70) == 0x10) i never had a problem with it
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-06-02 16:43 -0500 |
| Message-ID | <jqe18o$9of$1@dont-email.me> |
| In reply to | #21715 |
<snip>
Here's a terrible example:
http://icecube.wisc.edu/~dglo/c_class/const_vol.html
int
check_iobuf(void)
{
volatile int iobuf;
int val;
while (iobuf == 0) {
}
val = iobuf;
iobuf = 0;
return(val);
}
Unless I miss my guess, "iobuf" is an *auto*. It's
not mapped as a hardware register, no external
asynchronous process can change it.... it's on
the local stack...
I suppose you can have it be "extern volatile int iobuf" and
use the linker to put it in a hardware-interesting "segment"
but imagine the confusion promulgated by that bad example. it's
even apparently an infinite loop...
One compiler for 68000 used an "@" operator to
declare something as "int Thing = @0x50000;" for
this... I don't have an example and am working from memory.
--
Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-02 14:59 -0700 |
| Message-ID | <lnmx4lfk8a.fsf@nuthaus.mib.org> |
| In reply to | #21713 |
Les Cargill <lcargill99@comcast.com> writes:
> I am using Mingw 3.4.5 on a 'Doze box, but it pretty much
> follows any Gnu compiler I've run into.
>
> Why is this:
>
> ---------------------------
> #define SIZE 20
> const int size = SIZE;
> char array[SIZE];
> ---------------------------
>
> legal, yet
>
> ---------------------------
> #define SIZE 20
> const int size = SIZE;
> char array[size];
> ---------------------------
>
> not?
Both are legal if they occur inside a function definition, where the
second is a variable-length array (VLA) declaration.
At file scope, VLAs are not allowed.
Given:
const int size = 20;
"size" is still considered an ordinary object; a reference to it is
*not* a constant expression. Any compiler worth its salt will convert a
reference to that object to a literal 20 (assuming that results in
faster code), but that's an optimization; in the abstract machine it
fetches the value of the object (which will always be 20).
The key thing to remember is that the "const" keyword doesn't mean
"constant". A "constant" expression is one that can be (and in many
cases must be) evaluated at compile time. The "const" keyword really
means read-only. For example, the following is a perfectly legal
declaration (inside a function):
const int r = rand();
(Note that C++ has slightly different rules; in C++, a reference to
"size" *is* a constant expression.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-06-02 17:12 -0500 |
| Message-ID | <jqe303$id9$1@dont-email.me> |
| In reply to | #21724 |
Keith Thompson wrote: > Les Cargill<lcargill99@comcast.com> writes: >> I am using Mingw 3.4.5 on a 'Doze box, but it pretty much >> follows any Gnu compiler I've run into. >> >> Why is this: >> >> --------------------------- >> #define SIZE 20 >> const int size = SIZE; >> char array[SIZE]; >> --------------------------- >> >> legal, yet >> >> --------------------------- >> #define SIZE 20 >> const int size = SIZE; >> char array[size]; >> --------------------------- >> >> not? > > Both are legal if they occur inside a function definition, where the > second is a variable-length array (VLA) declaration. > I have not been able to find the -c99 switch for MingW 3.4.5.... don't think it does it... > At file scope, VLAs are not allowed. > > Given: > > const int size = 20; > > "size" is still considered an ordinary object; a reference to it is > *not* a constant expression. Any compiler worth its salt will convert a > reference to that object to a literal 20 (assuming that results in > faster code), but that's an optimization; in the abstract machine it > fetches the value of the object (which will always be 20). > Well, there you go. "const" isn't really const... it's a 'C' term of art.... > The key thing to remember is that the "const" keyword doesn't mean > "constant". A "constant" expression is one that can be (and in many > cases must be) evaluated at compile time. The "const" keyword really > means read-only. For example, the following is a perfectly legal > declaration (inside a function): > > const int r = rand(); > > (Note that C++ has slightly different rules; in C++, a reference to > "size" *is* a constant expression.) > Right! We are in an infinity of twisty mazes :) -- Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-02 18:27 -0700 |
| Message-ID | <lnfwadfalp.fsf@nuthaus.mib.org> |
| In reply to | #21725 |
Les Cargill <lcargill99@comcast.com> writes:
> Keith Thompson wrote:
[...]
> I have not been able to find the -c99 switch for MingW 3.4.5.... don't
> think it does it...
Try "-std=c99".
>> At file scope, VLAs are not allowed.
>>
>> Given:
>>
>> const int size = 20;
>>
>> "size" is still considered an ordinary object; a reference to it is
>> *not* a constant expression. Any compiler worth its salt will convert a
>> reference to that object to a literal 20 (assuming that results in
>> faster code), but that's an optimization; in the abstract machine it
>> fetches the value of the object (which will always be 20).
>>
>
> Well, there you go. "const" isn't really const... it's a 'C' term of
> art....
"const" is a C keyword. Unlike "constant", it's not an English word
with a pre-existing meaning. It means exactly what the language says it
means.
"const" does mean "const". It just doesn't mean "constant".
>> The key thing to remember is that the "const" keyword doesn't mean
>> "constant". A "constant" expression is one that can be (and in many
>> cases must be) evaluated at compile time. The "const" keyword really
>> means read-only. For example, the following is a perfectly legal
>> declaration (inside a function):
>>
>> const int r = rand();
>>
>> (Note that C++ has slightly different rules; in C++, a reference to
>> "size" *is* a constant expression.)
>>
>
> Right! We are in an infinity of twisty mazes :)
And even in C++, given:
const int r = rand();
a reference to r is not a constant expression. (It can't be; there's no
way to evaluate it at compile time.)
BTW, there is a limited workaround. If you want size to be a constant
expression, without using the preprocessor, you can write:
enum { size = 20 };
Enumeration constants are of type int, and references to them are
constant expressions. You can't use this to create constants of types
other than int, though.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-06-02 22:27 -0500 |
| Message-ID | <jqeldc$d40$1@dont-email.me> |
| In reply to | #21731 |
Keith Thompson wrote:
> Les Cargill<lcargill99@comcast.com> writes:
>> Keith Thompson wrote:
> [...]
>> I have not been able to find the -c99 switch for MingW 3.4.5.... don't
>> think it does it...
>
> Try "-std=c99".
>
>>> At file scope, VLAs are not allowed.
>>>
>>> Given:
>>>
>>> const int size = 20;
>>>
>>> "size" is still considered an ordinary object; a reference to it is
>>> *not* a constant expression. Any compiler worth its salt will convert a
>>> reference to that object to a literal 20 (assuming that results in
>>> faster code), but that's an optimization; in the abstract machine it
>>> fetches the value of the object (which will always be 20).
>>>
>>
>> Well, there you go. "const" isn't really const... it's a 'C' term of
>> art....
>
> "const" is a C keyword. Unlike "constant", it's not an English word
> with a pre-existing meaning. It means exactly what the language says it
> means.
>
> "const" does mean "const". It just doesn't mean "constant".
>
>>> The key thing to remember is that the "const" keyword doesn't mean
>>> "constant". A "constant" expression is one that can be (and in many
>>> cases must be) evaluated at compile time. The "const" keyword really
>>> means read-only. For example, the following is a perfectly legal
>>> declaration (inside a function):
>>>
>>> const int r = rand();
>>>
>>> (Note that C++ has slightly different rules; in C++, a reference to
>>> "size" *is* a constant expression.)
>>>
>>
>> Right! We are in an infinity of twisty mazes :)
>
> And even in C++, given:
>
> const int r = rand();
>
> a reference to r is not a constant expression. (It can't be; there's no
> way to evaluate it at compile time.)
>
> BTW, there is a limited workaround. If you want size to be a constant
> expression, without using the preprocessor, you can write:
>
> enum { size = 20 };
>
> Enumeration constants are of type int, and references to them are
> constant expressions. You can't use this to create constants of types
> other than int, though.
>
I like the enum trick - hadn't seen that before.
--
Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-03 11:24 +0100 |
| Message-ID | <jqfe45$q7d$1@dont-email.me> |
| In reply to | #21725 |
"Les Cargill" <lcargill99@comcast.com> wrote in message
news:jqe303$id9$1@dont-email.me...
> Keith Thompson wrote:
>> (Note that C++ has slightly different rules; in C++, a reference to
>> "size" *is* a constant expression.)
>>
>
> Right! We are in an infinity of twisty mazes :)
I've never got the hang of 'const' in C.
Using it like this:
const int a = 1000;
means a gets the value 1000, then can't be changed. OK.
Now you try this:
int b=2000;
const int* p = &b;
means, I think, that you can't change b via the the pointer. But you *can*
change p to point somewhere else. To protect p itself, it's necessary to
write:
int* const p = &b;
Now you can write: *p=3000; but you can't write p=&c. (I've just looked this
up online which is how I know...)
To keep p readonly, and not allow it's target to be changed either,
presumably you have to write:
const int * const p = &b;
Perfectly clear :-)
But, who care's about that; what I want to know is why, at some point during
the last forty years, didn't someone just add a feature like:
constant int d = 4000;
and it means exactly that: d is a synonym for the literal d. It has a
precise type, and follows normal scoping rules. You also can't use it as an
lvalue so it is guaranteed to have that value. It can also be used to
initialise fixed size arrays, and does not to be written in capitals.
It's a five-minute job to add to the language (exaggerating a little, but it
is pretty trivial to implement). Instead we have a series of unsatisfactory
alternatives: #define, const (which doesn't work, or works but you
unintentionally end up with a VLA), and enum{}, which you described as a
'trick'...
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-03 13:51 -0700 |
| Message-ID | <lny5o4dsqr.fsf@nuthaus.mib.org> |
| In reply to | #21745 |
"BartC" <bc@freeuk.com> writes:
[...]
> But, who care's about that; what I want to know is why, at some point
> during the last forty years, didn't someone just add a feature like:
>
> constant int d = 4000;
>
> and it means exactly that: d is a synonym for the literal d. It has a
> precise type, and follows normal scoping rules. You also can't use it
> as an lvalue so it is guaranteed to have that value. It can also be
> used to initialise fixed size arrays, and does not to be written in
> capitals.
>
> It's a five-minute job to add to the language (exaggerating a little,
> but it is pretty trivial to implement). Instead we have a series of
> unsatisfactory alternatives: #define, const (which doesn't work, or
> works but you unintentionally end up with a VLA), and enum{}, which
> you described as a 'trick'...
In fact someone did do that: Bjarne Stroustrup, when he was designing
C++.
Except that he didn't introduce a new keyword; he just tweaked the
semantics of "const".
In C++, if you declare
const some_type x = init_expr;
x becomes a constant expression *if* some_type is arithmetic *and*
init_expr is a constant expression. Otherwise, it has pretty much the
same meaning it has in C. (I probably haven't gotten that 100% right,
but that's the general idea.)
So, for example, in C++ (which doesn't have VLAs) you can have this:
{
const int array_size = 20;
int arr[arr_size];
}
but not this:
{
const int array_size = rand() % 20 + 1;
int arr[arr_size]; // invalid
}
I don't think it would have been terribly difficult for C to adopt this
feature, and I think it would have been a good idea. Maybe for C202x.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-04 12:20 +0100 |
| Message-ID | <jqi5mr$7qu$1@dont-email.me> |
| In reply to | #21766 |
"Keith Thompson" <kst-u@mib.org> wrote in message news:lny5o4dsqr.fsf@nuthaus.mib.org... > "BartC" <bc@freeuk.com> writes: >> why ... didn't someone just add a feature like: >> >> constant int d = 4000; > In fact someone did do that: Bjarne Stroustrup, when he was designing > C++. > > Except that he didn't introduce a new keyword; he just tweaked the > semantics of "const". > > In C++, if you declare > > const some_type x = init_expr; > > x becomes a constant expression *if* some_type is arithmetic *and* > init_expr is a constant expression. Otherwise, it has pretty much the > same meaning it has in C. (I probably haven't gotten that 100% right, > but that's the general idea.) It's taking a slightly tricky concept, a 'const' attribute, and making it even harder. Now it means read-only variables, read-only parameters, *and* named literals. Provided it can be agreed whether a particular right-hand expression is a constant or not; some compilers might be clever enough to evaluate the results of certain functions, others won't. And it's still not clear whether they are allowed as l-values or not. Although I suppose, compared with the rest of C++, no-one would really notice.. Using a new keyword and a new concept would keep things simple: it would only be used to apply a type and name to a literal. The right-hand-size *must* be a constant (on any compiler). You can't use them as l-values. And it would almost be the same as using the literal itself (the declaration may introduce a cast). However it would only make sense for primitives: values that could correspond to 'immediate' data in machine code, and which don't need any storage reserved. A named string literal doesn't work as well (as it would still need storage). -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Jens Gustedt <jens.gustedt@loria.fr> |
|---|---|
| Date | 2012-06-04 13:54 +0200 |
| Message-ID | <4FCCA1EA.9080101@loria.fr> |
| In reply to | #21805 |
Am 04.06.2012 13:20, schrieb BartC:
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lny5o4dsqr.fsf@nuthaus.mib.org...
>> "BartC" <bc@freeuk.com> writes:
>
>>> why ... didn't someone just add a feature like:
>>>
>>> constant int d = 4000;
>
>> In fact someone did do that: Bjarne Stroustrup, when he was designing
>> C++.
>>
>> Except that he didn't introduce a new keyword; he just tweaked the
>> semantics of "const".
>>
>> In C++, if you declare
>>
>> const some_type x = init_expr;
>>
>> x becomes a constant expression *if* some_type is arithmetic *and*
>> init_expr is a constant expression. Otherwise, it has pretty much the
>> same meaning it has in C. (I probably haven't gotten that 100% right,
>> but that's the general idea.)
>
> It's taking a slightly tricky concept, a 'const' attribute, and making it
> even harder. Now it means read-only variables, read-only parameters, *and*
> named literals. Provided it can be agreed whether a particular right-hand
> expression is a constant or not; some compilers might be clever enough to
> evaluate the results of certain functions, others won't. And it's still not
> clear whether they are allowed as l-values or not.
agreed
> Although I suppose, compared with the rest of C++, no-one would really
> notice..
:)
> Using a new keyword and a new concept would keep things simple: it would
> only be used to apply a type and name to a literal. The right-hand-size
> *must* be a constant (on any compiler). You can't use them as l-values. And
> it would almost be the same as using the literal itself (the declaration
> may introduce a cast).
No I don't think that a new keyword would be needed. Alowing const
qualified register "variables" in file scope would do the trick.
register struct toto const A = { .x = 42 };
would give you real literals for almost any data type. For such
variables no aliasing is possible (no one can take their adress) and so
they can be considered as real constants.
They could easily be declared-defined in any header file since they
wouldn't need to generate an external symbol.
Jens
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-04 14:32 -0700 |
| Message-ID | <lnlik2epbd.fsf@nuthaus.mib.org> |
| In reply to | #21805 |
"BartC" <bc@freeuk.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lny5o4dsqr.fsf@nuthaus.mib.org...
>> "BartC" <bc@freeuk.com> writes:
>
>>> why ... didn't someone just add a feature like:
>>>
>>> constant int d = 4000;
>
>> In fact someone did do that: Bjarne Stroustrup, when he was designing
>> C++.
>>
>> Except that he didn't introduce a new keyword; he just tweaked the
>> semantics of "const".
>>
>> In C++, if you declare
>>
>> const some_type x = init_expr;
>>
>> x becomes a constant expression *if* some_type is arithmetic *and*
>> init_expr is a constant expression. Otherwise, it has pretty much the
>> same meaning it has in C. (I probably haven't gotten that 100% right,
>> but that's the general idea.)
>
> It's taking a slightly tricky concept, a 'const' attribute, and making it
> even harder. Now it means read-only variables, read-only parameters, *and*
> named literals.
Variables and parameters are both objects, and "const" means the same
thing for both, so it's not as tricky as you imply.
> Provided it can be agreed whether a particular right-hand
> expression is a constant or not; some compilers might be clever enough to
> evaluate the results of certain functions, others won't. And it's still not
> clear whether they are allowed as l-values or not.
The C standard defines "constant expressions" unambiguously in section
6.6. A constant expression isn't merely an expression that some
particular compiler is able to evaluate at compile time.
The C++ standard does make it perfectly clear whether such constants are
allowed as lvalues. (I haven't found the relevant wording in the C++
standard, but g++ -pedantic allows it.)
> Although I suppose, compared with the rest of C++, no-one would really
> notice..
>
> Using a new keyword and a new concept would keep things simple: it would
> only be used to apply a type and name to a literal. The right-hand-size
> *must* be a constant (on any compiler). You can't use them as l-values. And
> it would almost be the same as using the literal itself (the declaration may
> introduce a cast).
Using the same mechanism that's been used in C++ for years would keep
things even simpler.
I certainly don't argue that C should adopt C++ features wholesale, but
in this case the way C++ does it is good enough, and *unnecessary*
incompatibilities are, well, unnecessary.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2012-06-02 23:50 +0100 |
| Message-ID | <pan.2012.06.02.22.50.02.517000@nowhere.com> |
| In reply to | #21713 |
On Sat, 02 Jun 2012 15:43:40 -0500, Les Cargill wrote:
> And yes, I understand/speak/grok preprocessor vs.
> compiler. I know *how*, I just wonder *why*. Is
> this a practical, strategic or tactical thing,
> or am I just being silly? Was it a conscious decision
> of the committee, or just one of those things?
K&R C didn't have "const". Along with "volatile", it was added during the
standardisation process to facilitate optimisation.
The main purpose of "const" is to tell the compiler to assume that the
value won't change. However, a const-qualified variable is still an
lvalue, not a compile-time constant; changing that was presumably
considered too radical.
If you want a compile-time integer constant, you can use enum, e.g.:
enum { size = SIZE };
This "trick" is still quite common in C++ code due to some compilers being
a bit late to accept that a "static const" member really is a compile-time
constant in C++, and the preprocessor not being an acceptable substitute
when the name has to belong to a class or namespace.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-06-03 10:53 +1200 |
| Message-ID | <a2vjr4F47cU5@mid.individual.net> |
| In reply to | #21727 |
On 06/ 3/12 10:50 AM, Nobody wrote:
> On Sat, 02 Jun 2012 15:43:40 -0500, Les Cargill wrote:
>
>> And yes, I understand/speak/grok preprocessor vs.
>> compiler. I know *how*, I just wonder *why*. Is
>> this a practical, strategic or tactical thing,
>> or am I just being silly? Was it a conscious decision
>> of the committee, or just one of those things?
>
> K&R C didn't have "const". Along with "volatile", it was added during the
> standardisation process to facilitate optimisation.
>
> The main purpose of "const" is to tell the compiler to assume that the
> value won't change. However, a const-qualified variable is still an
> lvalue, not a compile-time constant; changing that was presumably
> considered too radical.
>
> If you want a compile-time integer constant, you can use enum, e.g.:
>
> enum { size = SIZE };
>
> This "trick" is still quite common in C++ code due to some compilers being
> a bit late to accept that a "static const" member really is a compile-time
> constant in C++, and the preprocessor not being an acceptable substitute
> when the name has to belong to a class or namespace.
Only in code written in the last century!
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2012-06-03 14:35 +0100 |
| Message-ID | <pan.2012.06.03.13.35.48.626000@nowhere.com> |
| In reply to | #21728 |
On Sun, 03 Jun 2012 10:53:24 +1200, Ian Collins wrote:
>> If you want a compile-time integer constant, you can use enum, e.g.:
>>
>> enum { size = SIZE };
>>
>> This "trick" is still quite common in C++ code due to some compilers being
>> a bit late to accept that a "static const" member really is a compile-time
>> constant in C++, and the preprocessor not being an acceptable substitute
>> when the name has to belong to a class or namespace.
>
> Only in code written in the last century!
Or code intended to work with compilers written in the last century.
For large code bases, it's not uncommon to just keep using the compiler
for which the very first lines of code were written, which then requires
keeping all subsequent code compatible with that compiler.
Although I don't think you'd actually have to go back 12 years to find a
compiler that didn't handle "static const" correctly.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-02 21:11 -0400 |
| Message-ID | <jqedjj$9gi$1@dont-email.me> |
| In reply to | #21727 |
On 06/02/2012 06:50 PM, Nobody wrote: ... > The main purpose of "const" is to tell the compiler to assume that the > value won't change. I don't think that's the main purpose. In my opinion, the most important thing about 'const', and the reason why I use it where appropriate, is that it turns many dangerous constructs into constraint violations, making a diagnostic mandatory. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web