Constant strings

B

BartC

James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL,
but
also in the C type syntax there doesn't seem anywhere to put a const for
an
array.

What does CDECL say about

const int array[5];

'const int ax[5]' results in ax (because 'array' is special) declared as:

'array 5 of const int'

So you can apply const to elements, but not to arrays (at least not without
the trick that Martin posted).

Although a const array, and an array of const elements, achieve the same
thing, it still appears the case that an array itself can't be const. (Even
when using a typedef to apparently apply const to an array, I think it is
applied instead to the elements.)
 
K

Keith Thompson

James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL, but
also in the C type syntax there doesn't seem anywhere to put a const for an
array.

What does CDECL say about

const int array[5];

It says "syntax error", but only because cdecl apparently treats "array"
as a reserved word (arguably a bug in cdecl).

cdecl> explain const int array[5]
syntax error
cdecl> explain const int arr[5]
declare arr as array 5 of const int
cdecl>

I believe that "const" does, at least syntactically, apply to the
element type, not to the array. But there's no practical difference; an
array value consists exactly of the values of the elements, and an array
is read-only if and only if its elements are read-only.
 
K

Keith Thompson

BartC said:
Maybe because 'array' doesn't really exist as an independent type,
outside of a type-specification; the type of an expression can never
start with 'array', so having 'const array' would have no benefit.

It's not true that array types don't exist as independent types, merely
that arrays decay to pointers in most contexts. The operand of unary
"sizeof" or "&" can be an expression of array type, and that expression
does not decay to a pointer.

But you're probably right about "const array" being unnecessary, since
"const" applies to the element type -- but it doesn't make much
difference.

An example:

const int arr[3] = { 10, 20, 30 };

&arr has type "pointer to array 3 of const int".
&arr[0] has type "pointer to const int".
 
K

Keith Thompson

Keith Thompson said:
BartC said:
(11) Read-only attributes can be applied to scalars, structs and pointers,
but not to arrays.
[...]

const int array[3] = { 10, 20, 30 };

Which (I think) actually applies the `const` to the element type, not to
the array type. I should have read the rest of the thread before
posting.
 
J

James Kuyper

James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL,
but
also in the C type syntax there doesn't seem anywhere to put a const for
an
array.

What does CDECL say about

const int array[5];

'const int ax[5]' results in ax (because 'array' is special) declared as:

'array 5 of const int'

So you can apply const to elements, but not to arrays (at least not without
the trick that Martin posted).

What do you think it would mean for the array to be const, that is
different from having the elements of the array being const?
 
S

Stephen Sprunk

At least hypothetically, ftell might be returning a handle to an
allocated structure on systems where the notion of position in a
text file is more complex than the stream-of-bytes model*. In that
case it might be necessary to track the allocated structures so they
can be discarded when the file is closed.

I thought of that. It seems easier to keep said structure within the
FILE object itself since there will can only be one valid one at a given
time; the reading functions would update it to keep it current, so
ftell() still just has to extract its value (perhaps after some
computation).

Allocating a new structure every time someone calls ftell() seems
wasteful and inefficient; it would monotonically consume more and more
memory until they eventually call fclose().

S
 
B

BartC

James Kuyper said:
On 04/24/2014 10:09 AM, BartC wrote:

What do you think it would mean for the array to be const, that is
different from having the elements of the array being const?

I suppose a difference could be invented, especially if an array was a
proper first class type (although I'm the wrong person to suggest a new use
for const.)

But I'm not demanding that arrays ought to have the const attribute. I was
just pointing out a mild anomaly in the type system and the way that consts
can be applied. So you have to say 'array of const T', and not 'const array
of T' or 'const array of const T' (just to make doubly sure).
 
S

Stephen Sprunk

What do you think it would mean for the array to be const, that is
different from having the elements of the array being const?

I'd expect a const array of int to decay to a const pointer to int,
which is quite different from a pointer to const int.

OTOH, you can't modify the decayed-to pointer anyway, so wouldn't that
mean that they're already effectively const?

S
 
J

James Kuyper

I suppose a difference could be invented, especially if an array was a
proper first class type (although I'm the wrong person to suggest a new use
for const.)

But I'm not demanding that arrays ought to have the const attribute. I was
just pointing out a mild anomaly in the type system and the way that consts
can be applied. So you have to say 'array of const T', and not 'const array
of T' or 'const array of const T' (just to make doubly sure).

The standard does identify "const T[]" as declaring an "array of const
T" . However, I would consider "const array of T" to clearly be an
alternative (though non-standard) way of describing the same type.
"const array of const T, on the other hand, is simply meaningless.
 
S

Stephen Sprunk

That is not comparable to removing const; const is not involved in
any decisions involving polymorphic dispatch. It does not provide
type inference.

In C++ it does, and so in C++ you cannot remove const from programs,
in general, without turning them into a mess that requires a
diagnostic.

Without references, any non-trivial C++ program would infinitely recurse
at the first copy constructor it encountered, and references are unsafe
without const.

Once C++ needed const for references, it needed them for pointers since
that's how references are implemented, and extending const to the rest
of the type system was obvious. Then const migrated to C, for
consistency and (most importantly) headers that are compiled in both
languages.
When const is fastidiously applied throughout a code base (it
adheres to "const correctness") then programmers are free to assume
that if a function has a "const type *x" parameter, then the function
does not modify *x. And, conversely, if the parameter is "type *x",
there is a strong reason to suspect that the funtion does modify *x;
because otherwise, in keeping with "const correctness", it would have
been declared otherwise.

This can be helpful, because it is quite important to know which
functions parameters are pure, and which mutate. If the declaration,
or a comment next to it, do not answer the question, the programmer
has to waste time investigating this.

Also, if a function takes a const argument, then it can only pass it to
other functions taking a const argument. This often results in what is
known as "const poisoning": if one function uses const, it ends up
spreading across the entire codebase. OTOH, this process tends to
uncover latent bugs, so it's actually good for you in the end.

S
 
K

Keith Thompson

Stephen Sprunk said:
I'd expect a const array of int to decay to a const pointer to int,
which is quite different from a pointer to const int.

Really? I wouldn't expect that. If I had a read-only array, I'd
expect its elements to be read-only. The fact that C apparently
doesn't have a way to express "const array" is probably just an
accident of the syntax, and one that doesn't cause any harm since
we specifying "const" on the element type does the same thing.
(I haven't taken the time to think about whether typedefs affect
this.)
OTOH, you can't modify the decayed-to pointer anyway, so wouldn't that
mean that they're already effectively const?

The pointer to which an array expression decays is not an lvalue.
"const" is irrelevant for non-lvalues, since there's nothing to modify.
(42++?)
 
G

glen herrmannsfeldt

Stephen Sprunk said:
On 23-Apr-14 23:53, Robert Wessel wrote:
(snip)
I thought of that. It seems easier to keep said structure within the
FILE object itself since there will can only be one valid one at a given
time; the reading functions would update it to keep it current, so
ftell() still just has to extract its value (perhaps after some
computation).

If the structure was a list of block offsets, it would slowly increase
as the file got longer. There are at least a few different ways of
storing such a table, some of which might modify the FILE struct.
Allocating a new structure every time someone calls ftell() seems
wasteful and inefficient; it would monotonically consume more and more
memory until they eventually call fclose().

Not every time, but some of the times.

If you read from the beginning, counting bytes, for each ftell(),
you might at least want to cache the previous value. That would
be one write to the FILE struct, but it wouldn't get bigger.
Or cache a small number of offsets.

-- glen
 
S

Stephen Sprunk

If the structure was a list of block offsets, it would slowly increase
as the file got longer. There are at least a few different ways of
storing such a table, some of which might modify the FILE struct.

Wouldn't that only happen during reads or writes to the file, though,
which obviously require a non-const FILE? ftell() would just read the
tables, which could be done with a const FILE.
Not every time, but some of the times.

If you read from the beginning, counting bytes, for each ftell(),
you might at least want to cache the previous value. That would
be one write to the FILE struct, but it wouldn't get bigger.
Or cache a small number of offsets.

Caching is one justification for casting away constness. Since we're
talking about implementation internals, one could take advantage of
knowledge that doing so is "safe" on that implementation.

(AIUI, C++ allows this for const objects via mutable members.)

S
 
B

Ben Bacarisse

Keith Thompson said:
James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL, but
also in the C type syntax there doesn't seem anywhere to put a const for an
array.

What does CDECL say about

const int array[5];

It says "syntax error", but only because cdecl apparently treats "array"
as a reserved word (arguably a bug in cdecl).

cdecl> explain const int array[5]
syntax error
cdecl> explain const int arr[5]
declare arr as array 5 of const int
cdecl>

I believe that "const" does, at least syntactically, apply to the
element type, not to the array. But there's no practical difference; an
array value consists exactly of the values of the elements, and an array
is read-only if and only if its elements are read-only.

I suppose it depends on what is practical, but there is a difference: a
const array and an array with const elements are not compatible types
(at least that's how I read things).
 
J

Joe Pfeiffer

Keith Thompson said:
James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL, but
also in the C type syntax there doesn't seem anywhere to put a const for an
array.

What does CDECL say about

const int array[5];

It says "syntax error", but only because cdecl apparently treats "array"
as a reserved word (arguably a bug in cdecl).

cdecl> explain const int array[5]
syntax error
cdecl> explain const int arr[5]
declare arr as array 5 of const int
cdecl>

I believe that "const" does, at least syntactically, apply to the
element type, not to the array. But there's no practical difference; an
array value consists exactly of the values of the elements, and an array
is read-only if and only if its elements are read-only.

So... does anybody know what cdecl does with "array" that making it a
reserved word makes sense? Or is it plain and simply a bug?
 
S

Stephen Sprunk

Really? I wouldn't expect that. If I had a read-only array, I'd
expect its elements to be read-only.

That'd be an array of const int, not a const array of int.
The fact that C apparently doesn't have a way to express "const array"
is probably just an accident of the syntax,

Perhaps, though I think it's more historical artifact than accident.

In B, an array was just a pointer to an unnamed object; one could modify
an array to point elsewhere just like any other pointer. When arrays
became a distinct type (arguably what makes C a different language),
they became inherently unmodifiable, but they decayed to pointers in
most contexts for backwards compatibility. That predated const, though,
so perhaps arrays would have been described differently if that change
had been later.

I just noticed an interesting parallel to functions, which also decay to
pointers in most contexts and can't meaningfully be declared const
because they're already inherently unmodifiable. Two such similar
accidents would be quite a coincidence.
and one that doesn't cause any harm since we specifying "const" on the
element type does the same thing. (I haven't taken the time to think
about whether typedefs affect this.)

I think someone mentioned upthread that one can actually create a const
array (rather than an array of const) using a typedef. I'm not sure how
it could behave any differently from a non-const array, though.
The pointer to which an array expression decays is not an lvalue.
"const" is irrelevant for non-lvalues, since there's nothing to
modify. (42++?)

That was my point. (But see above about B.)

S
 
K

Keith Thompson

Joe Pfeiffer said:
Keith Thompson said:
James Kuyper said:
On 04/24/2014 08:15 AM, BartC wrote:
...
I can't get CDECL to accept 'const array'. That might be a bug in CDECL, but
also in the C type syntax there doesn't seem anywhere to put a const for an
array.

What does CDECL say about

const int array[5];

It says "syntax error", but only because cdecl apparently treats "array"
as a reserved word (arguably a bug in cdecl).

cdecl> explain const int array[5]
syntax error
cdecl> explain const int arr[5]
declare arr as array 5 of const int
cdecl>

I believe that "const" does, at least syntactically, apply to the
element type, not to the array. But there's no practical difference; an
array value consists exactly of the values of the elements, and an array
is read-only if and only if its elements are read-only.

So... does anybody know what cdecl does with "array" that making it a
reserved word makes sense? Or is it plain and simply a bug?

It's a reserved word in the English-like syntax it uses to explain
declarations:

cdecl> explain int arr[42]
declare arr as array 42 of int
cdecl> explain int array[42]
syntax error
cdecl>

This *shouldn't* cause it to be reserved for the C-like syntax it uses,
but apparently it treats it that way. I've never looked into the
internals, so I can't be sure what's going on.

The word "pointer" is also reserved, and "ptr" is a synonym for it.
 
J

James Kuyper

On 24-Apr-14 14:32, Keith Thompson wrote: ....

That'd be an array of const int, not a const array of int.

So, what does "const array of int" mean to you? If it were possible to
declare a const array of int, how would you describe the way in which it
differs from an ordinary array of int?

....
I think someone mentioned upthread that one can actually create a const
array (rather than an array of const) using a typedef. I'm not sure how
it could behave any differently from a non-const array, though.

That is the question I'd like answered. I don't understand what people
think they mean by that term that makes it different from "array of
const int".
 
B

Ben Bacarisse

Keith Thompson said:
Joe Pfeiffer <[email protected]> writes:
So... does anybody know what cdecl does with "array" that making it a
reserved word makes sense? Or is it plain and simply a bug?

It's a reserved word in the English-like syntax it uses to explain
declarations:

cdecl> explain int arr[42]
declare arr as array 42 of int
cdecl> explain int array[42]
syntax error
cdecl>

This *shouldn't* cause it to be reserved for the C-like syntax it uses,
but apparently it treats it that way. I've never looked into the
internals, so I can't be sure what's going on.

cdecl uses the same grammar for both "directions" of it's translation.
'array' is a keyword when used like this:

cdecl> declare arr as array 42 of int
int arr[42]

so it's also one when reading an 'explain' command. You can't name your
array "declare", "explain", "help" or any number of other words that are
considered special. It's a shame, because the error that gets reported
might be confusing. Is it really a syntax error in the declaration, or
did you just use a keyword without knowing?

Even when this is taken into account, cdecl is rather lax in admitting
some things that are not valid C, and rejecting others that are (though
the latter may just be that it has not kept up with recent standards).

<snip>
 
M

Martin Shobe

So, what does "const array of int" mean to you? If it were possible to
declare a const array of int, how would you describe the way in which it
differs from an ordinary array of int?

...

That is the question I'd like answered. I don't understand what people
think they mean by that term that makes it different from "array of
const int".

As far as I can tell, the difference is conceptual. A "const array of
int" would mean that the array, as a whole, would be const. An "array of
const int" would mean the each element of the array would be const. I'm
unaware of any practical differences.

Martin Shobe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,121
Latest member
LowellMcGu
Top