David Brown said:
On 08/05/14 11:15, BartC wrote:
If the choice is *only* between 0 and 1, then 0 is more versatile. But
it's
not hard to allow both or any. Both 0 and 1 bases have their uses;
1-based I
think is more useful as the default base.
When you just going to have one type of array, then indexing by
integers
starting from 0 is the simplest and clearest - you have the offset from
the start of the array.
But it doesn't always make sense to keep thinking of offsets. Look at
the
'A'..'Z' example below, and tell me where offsets from the start of the
array come in, on the line with rotationcypher['F'].
The point is that when you use 0-based arrays, you can think of offsets.
For non-zero based arrays, the compiler hides the offset from you. In
the 'a' .. 'z', the compiler would put the " -'a' " in for you.
Exactly. So why shouldn't there be the option for a lower bound that isn't
zero? As you say, it's not that difficult for a compiler to deal with it.
The problem is not in the compiler - it could add the "-'a'" when
accessing the array, or it could (on most targets, in most situations)
do the subtraction on the symbol at link time.
The problem is user expectations, along with the expectations of other
tools that read or write C code. It is a fundamental part of the
definition of C that if xs is an array, then xs and xs[0] have the same
address, and a pointer to xs[0] is the same as xs. Allowing non-zero
lower bounds breaks that rule.
In languages like Pascal or Ada, there never was such a rule - so there
never has been such an assumption. In C++, the rule is true for POD
arrays (inherited from C), but not for classes with a [] operator, and
it is fine to have different lower bounds or different types for the
indices. But making lower bounds non-zero would break C, so it is not
going to happen (at least, not without a lot of effort, and perhaps some
new syntax to make things clear).
As I said, I have no argument against it being a nice feature that would
make some code clearer and give better compile-time checking. I just
don't see it happening in C.
I can write this [** not in C **]:
['A'..'Z']char rotationcypher
That format is pointlessly different from C style - if these sorts of
arrays are ever to make sense in C, C++, or a C-like language, then they
would be written in roughly the form I gave.
I said that was not C. I wrote it that way because it is *an actual working
example* of a language that does C-like things yet allows any array lower
bound. And that C output was actual output (with some types adjusted to
make
it clearer).
In C you'd put the dimensions where it normally expects them (I don't know
what syntax would be proposed. I use either [lower..upper] or
[lower:length] or [length] or [lower:].)
I think the "[lower:]" syntax is /definitely/ optimistic for C.
Infinite lists are common in functional programming languages, but we
won't see lazy evaluation in C in the near future!
I can't make sense of you here. I said specifically that arrays with
ranges or enumerated types as indexes "would lead to clearer code and
better compile-time checking for ranges and types". I am not "trying to
deny this to C programmers" - I think it would be a useful enhancement
to the language, which is why I wrote about it.
I think that simply having a choice of lower bound would also be a useful
enhancement, and one considerably simpler to implement than turning C into
Pascal or Ada at the same time, with all these type checks (which are much
more difficult than you might think when you do it properly).
The compiler can do range checking it if likes. But at present, an array
like char a[100] already has a range of 0..99, and few compilers seem to
bother checking it! (A quick test shows only 2 out of 6 checking it at
normal warning levels. gcc doesn't seem to be it any any level, but
doubtless there will be an option hidden away to do so.)
gcc checks array bounds at compile time, but only if you have at least
-O2 or -Os optimisation (and -Wall), as the optimisation passes are used
to collect the information needed for checking. There are a number of
gcc warnings that only work (or only work well) with optimisation enabled.
I would say that compile-time checking of types and bounds is essential
to such a feature - the whole point would be to help write better code,
and that means making it easier for the programmer to write clearer code
and also making it easier for the tools to spot mistakes.
A decision to switch languages is not really an answer! (And it sounds like
C++ only manages it with some trouble.)
Anyway not everyone likes to drag in the complexity of a C++ compiler just
for one or two extra features which ought to be in C already.
A lot of people use C++ as ABC - "A Better C". It is not necessarily a
bad idea. And while C++ introduces a lot of extra complexity, it has
got a bit easier with C++11 "auto", which can save a lot of messy
template typing.