Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #21713 > unrolled thread

Array sizes and const

Started byLes Cargill <lcargill99@comcast.com>
First post2012-06-02 15:43 -0500
Last post2012-06-08 20:30 -0700
Articles 20 on this page of 51 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#21713 — Array sizes and const

FromLes Cargill <lcargill99@comcast.com>
Date2012-06-02 15:43 -0500
SubjectArray 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]


#21714

FromIan Collins <ian-news@hotmail.com>
Date2012-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]


#21715

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-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]


#21718

FromLes Cargill <lcargill99@comcast.com>
Date2012-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]


#22005

Fromjgk@panix.com (Joe keane)
Date2012-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]


#22082

Fromjgk@panix.com (Joe keane)
Date2012-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]


#21720

FromLes Cargill <lcargill99@comcast.com>
Date2012-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]


#21724

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#21725

FromLes Cargill <lcargill99@comcast.com>
Date2012-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]


#21731

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#21735

FromLes Cargill <lcargill99@comcast.com>
Date2012-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]


#21745

From"BartC" <bc@freeuk.com>
Date2012-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]


#21766

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#21805

From"BartC" <bc@freeuk.com>
Date2012-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]


#21810

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-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]


#21834

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#21727

FromNobody <nobody@nowhere.com>
Date2012-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]


#21728

FromIan Collins <ian-news@hotmail.com>
Date2012-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]


#21749

FromNobody <nobody@nowhere.com>
Date2012-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]


#21730

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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