Is enum a suitable way to implement a "local define?"

B

BartC

James Kuyper said:
On 04/07/2014 11:52 AM, BartC wrote:
The idea that there's a unique behavior associated with a C expression
ignores the fact that the meaning of C expressions depend upon the
context in which they are used. In particular, I'd expect quite
different behavior for the expression 'x' in a=x, b=&x, c=sizeof(x), and
d=_Alignof(x).

Suppose x *was* the number 7091; how many of those would still work? We are
only talking about an alias for 7091, without turning it into a full
variable which is the danger when you try a use an inappropriate feature
(read-only variables) to implement something that really needs to be done
properly. /Even if/ a smart-enough compiler can end up generating the same
code.

But see my reply to David Brown (time-stamped a similar time to this) which
is longer.
 
B

BartC

David Brown said:
On 07/04/14 17:52, BartC wrote:
[On the distinction between an actual constant, a named actual constant, and
a variable that may or may not have a read-only attribute]
Yes, we should forget about these distinctions. They are not true or
realistic anyway, so why try to pretend that they are?
Remember, a C compiler is /not/ a translator - it does not translate C
source code into assembly. It takes a /description/ or /specification/
of a task, written in the more-or-less carefully defined language C, and
generates object code that will have the same /visible/ effect as the
specified task.

The distinction can be there in the /language/. Clearly not directly in C
because it doesn't have such a language construct, but some people who want
to code would like to have it because it makes certain things obvious and
not a consequence of a whim of a compiler writer.

With C, you can write 5678, but not &5678.

You can declare a variable xyz, and write as xyz to obtain the value, or as
&xyz to obtain its name (ie. a constant pointer value).

Why can't I declare abc as a synonym for 5678, but be stopped from writing
&abc? After all I can used #define or enum to declare abc, with some
limitations, and I can't write &abc then either.

Instead of a simple, logical extension to allow such a declaration, where it
will be completely obvious what it is and what it can do, you instead
propose using a *variable* for the purpose, which so many issues associated
with it that I hardly know where to start! But I will have a go:

o You expect users to apply a 'read-only' attribute to a /variable/, as a
hint to a compiler, so that it can pick up its initialisation value, if
there is one, and treat that as though it is a simple named constant. That
is going around the houses a little!

o It is necessary to use either 'static const int' or 'const int', although
I'm not sure what the difference is between them (that with static const, it
can only be initialised to a constant expression)?

o 'static const int' doesn't need an initialisation value! (Presumably this
is then set to zero, but for a mechanism designed to define constant values,
this is a bigger sin that omitting an explicit type.) ('const int' doesn't
need one either, and the value then is undefined.)

o 'const int' can be set to a runtime value! Presumably such a name cannot
be used as a simple named constant; or can it? The possibilities are
complicated.

o 'const int' variables can, in certain circumstances, have their values
changed, so will differ from what the compiler thinks they might be.

o '[static] const int]' exists now in C, yet cannot be used for dimensioning
arrays or switch case-values. Maybe I missed something in the discussion,
but why is that? And what will change in future as apparently you are not
proposing any new syntax.

o I've just tried using a 'const int' value to define an array, and this
time it worked. Then I realised I was probably creating a VLA. I don't want
to inadvertently construct VLAs!

So, full of difficulties, so I don't understand your objection to my very
simple proposal, which has few of those problems:

o The name created is *not* a variable
o The initialisation value is mandatory, and *must* be evaluable at
compile-time
o The value will *never* change, and you can never take its address
o It can be used to dimension non-VLA arrays, as switch case-values, and can
be used to construct other such values
(Of course, there are some compilers that are so simple in construction
that they are basically translators, but that does not apply to "big"
compilers, and it is certainly not required by the C standards.)

You can't propose an essential language feature and then say you need an
elite compiler to implement it properly!

(And it might be true that some processors are not so good with immediate
values and they will require storage anyway; that should not affect the
abstract view of the language; if you are still going to separate naked
constants and named variables, then the idea of a named constant should also
be distinct.)
 
J

James Kuyper

Suppose x *was* the number 7091; how many of those would still work? ...

a=x, c=sizeof(x), and d=_Alignof(x). The only one disallowed would be
&x, which is the same thing I've already said about 1233. Did you expect
a different answer for 7091? What was the point of your question?
 
B

BartC

Seungbeom Kim said:
That rule ("declaration mimics use") by itself is not bad, I think,

Actually it was a terrible idea.
but the problem lies in the fact that * is prefix, while [] and () are
postfix. Had C had a postfix pointer indirection operator, such as ^
in Pascal, both expressions and declarations would've been clearer.

int ap[2]^; // ap is an array of 2 pointers to int
// ap is an int^, ap^ is an int
int pa^[2]; // pa is a pointer to an array of 2 ints
// pa^ is an int[2], pa^ is an int

const char p^^; // p is a pointer to a pointer to const char
char p^ const^; // p is a pointer to a const pointer to char
char p const^^; // p is a const pointer to a pointer to char


Stop right there - I can't help noticing that in your comments, you are
describing the type from left to right.

Doesn't that suggest that, for the purposes of constructing, reading and
understanding such types, that a left-to-right order is the natural one?

Your examples, using ^ instead of * for 'pointer to', would become, using
left to right notation:
const char p^^; // p is a pointer to a pointer to const char

^^const char p;
char p^ const^; // p is a pointer to a const pointer to char

^const ^char p;
char p const^^; // p is a const pointer to a pointer to char

const ^^char p;

Your comments were transcribed directly. It couldn't be simpler, in fact
translating to and from English is completely trivial. (The English puts the
name at the start, but such a style doesn't suit C.)
And it->member would have been equivalent to it^.member,
which doesn't require a pair of parentheses. Moreover,
probably we wouldn't have needed the -> operator at all.

I understand your point about having dereference as a postfix operator.
Maybe we'd have ended up with fewer parentheses, but moved even more things
to the wrong side!

(But I've used such an operator, and it causes problems when combined with
++ or --, which can end up needing extra parentheses.)
 
I

Ian Collins

BartC wrote:

So, full of difficulties, so I don't understand your objection to my very
simple proposal, which has few of those problems:

o The name created is *not* a variable
o The initialisation value is mandatory, and *must* be evaluable at
compile-time
o The value will *never* change, and you can never take its address
o It can be used to dimension non-VLA arrays, as switch case-values, and can
be used to construct other such values

With the exception of not having an address, C++'s constexpr meets your
requirements. I don't see why having an address is an issue if the
value is immutable.
 
G

glen herrmannsfeldt

(snip)
The distinction can be there in the /language/. Clearly not directly in C
because it doesn't have such a language construct, but some people who want
to code would like to have it because it makes certain things obvious and
not a consequence of a whim of a compiler writer.
With C, you can write 5678, but not &5678.
You can declare a variable xyz, and write as xyz to obtain the value, or as
&xyz to obtain its name (ie. a constant pointer value).
Why can't I declare abc as a synonym for 5678, but be stopped from writing
&abc? After all I can used #define or enum to declare abc, with some
limitations, and I can't write &abc then either.

Some years ago when C enum was added to Fortran (as part of the
C interoperabity feature) I had wondered about this. For one,
Fortran doesn't call by value, but normally (though not required)
call by reference. (Call by value result is also allowed.)

In C, enum constants are int, even when enum variables are not,
but I believe in Fortran the constants are the same type (KIND)
as variables. Otherwise, call by reference would fail.

Also, you are not supposed to modify a constant.

-- glen
 
B

BartC

James Kuyper said:
a=x, c=sizeof(x), and d=_Alignof(x). The only one disallowed would be
&x, which is the same thing I've already said about 1233. Did you expect
a different answer for 7091? What was the point of your question?

Sorry, I've lost the thread a bit!

We were talking about constants, and variables, and ways to name a constant
without turning it into a variable.

Clearly I'm not putting across my ideas well, so I will leave it.
 
B

BartC

Ian Collins said:
BartC wrote:



With the exception of not having an address, C++'s constexpr meets your
requirements. I don't see why having an address is an issue if the value
is immutable.

Possibly. But this is about C.

As for my requirements, it's just having a simple feature the equivalent of
Pascal's CONST, or any assembler's EQU, without having to drag variables
into it, which is a much harder, and less natural way of achieving it. I
don't know why I'm having such a hard time convincing people that it would
be a good idea to have in C, because at present there is no satisfactory,
general way of doing this.

However, because this is about the C source language, it is less my concern
now as I am moving away from actually having to use it. I just sort of feel
sorry for people who continue to have to battle with such things!

(If I generate C code, then my named constants get written out as naked
constants in C, completely bypassing the problem. And I am currently moving
away from that too, and generating native code directly, eliminating a lot
of C compiler and language problems, but not all.)
 
S

Stephen Sprunk

With C, you can write 5678, but not &5678.

You can declare a variable xyz, and write as xyz to obtain the value,
or as &xyz to obtain its name (ie. a constant pointer value).

Unless you give it "register" storage class.
Why can't I declare abc as a synonym for 5678, but be stopped from
writing &abc?

You can do the latter, at least; see above.
o You expect users to apply a 'read-only' attribute to a /variable/,

The term is "object", not "variable".
o 'const int' can be set to a runtime value! Presumably such a name
cannot be used as a simple named constant; or can it? The
possibilities are complicated.

o 'const int' variables can, in certain circumstances, have their
values changed, so will differ from what the compiler thinks they
might be.

If the object is "const int", then changing its value invokes UB.

Things get trickier when you pass a pointer-to-int to a function taking
pointer-to-const-int, since AFAIK the pointed-to value may change
without the compiler's knowledge despite being const.

S
 
S

Stephen Sprunk

To change that is to change a core part of C: declaration mimics use.

That rule ("declaration mimics use") by itself is not bad, I think,
but the problem lies in the fact that * is prefix, while [] and () are
postfix. Had C had a postfix pointer indirection operator, such as ^
in Pascal, both expressions and declarations would've been clearer.

From "The Development of the C Language" by Dennis M. Ritchie:

"Declarations in C must be read in an `inside-out' style that many find
difficult to grasp [Anderson 80]. Sethi [Sethi 81] observed that many of
the nested declarations and expressions would become simpler if the
indirection operator had been taken as a postfix operator instead of
prefix, but by then it was too late to change."

S
 
I

Ian Collins

BartC said:
Possibly. But this is about C.

The discussion looks like it is about an extension to C. C++'s
constexpr would be a useful extension to C that meets your requirements.
As for my requirements, it's just having a simple feature the equivalent of
Pascal's CONST, or any assembler's EQU, without having to drag variables
into it, which is a much harder, and less natural way of achieving it. I
don't know why I'm having such a hard time convincing people that it would
be a good idea to have in C, because at present there is no satisfactory,
general way of doing this.

A constexpr isn't a variable.
 
J

James Kuyper

David Brown said:
On 07/04/14 17:52, BartC wrote:
[On the distinction between an actual constant, a named actual constant, and
a variable that may or may not have a read-only attribute]
Yes, we should forget about these distinctions. They are not true or
realistic anyway, so why try to pretend that they are?
Remember, a C compiler is /not/ a translator - it does not translate C
source code into assembly. It takes a /description/ or /specification/
of a task, written in the more-or-less carefully defined language C, and
generates object code that will have the same /visible/ effect as the
specified task.

The distinction can be there in the /language/. Clearly not directly in C
because it doesn't have such a language construct, but some people who want
to code would like to have it because it makes certain things obvious and
not a consequence of a whim of a compiler writer.

If you care which method the compiler writer uses, C isn't the language
for you. The whole point of using C is to save you the work of having to
specify such things, leaving it up to the compiler. If you don't trust
the compiler, don't use a language that gives the compiler a choice - C
is very deliberately NOT such a language.

....
o It is necessary to use either 'static const int' or 'const int', although
I'm not sure what the difference is between them (that with static const, it
can only be initialised to a constant expression)?

It depends upon the scope. It's stupid that C gives two entirely
different meanings to 'static' (there's also a third one that's not
relevant to this question); but it's a historical artifact, and changing
the standard now to cleanly separate the two concepts would break too
much code.

At block scope, static determines whether the variable has automatic or
static storage duration. Now, you can't write code with defined behavior
that changes the value of the variable, and if it has automatic storage
duration, there's no way to write code with defined behavior that checks
what the value is between calls to the function. Therefore, a conforming
implementation could treat a "const int" precisely the same as a "static
const int", reducing unnecessary memory usage and unnecessary
re-initialization.

That's not quite true; a block scope "static const int" would have the
same exact address during every pass through function. That could also
be true if it had automatic storage duration, so is not itself a problem
- unless the function is directly or indirectly recursive, and compares
the addresses. It's not clear to me that optimizing "const int" by
treating it the same as "static const int" would be permitted for
recursive functions - which is an argument for explicitly using "static
const int".

At file scope, "static" determines whether the variable has internal or
external linkage. If it has internal linkage, and the program never
takes it's address, no actual storage need be allocated for it, the same
as at block scope. However, if it has external linkage, then there can
only be one definition for the variable across all of the translation
units that make up the program. It's value would have to be unknown in
every translation unit other than the one where it is defined. As a
result, it wouldn't be a compile time constant in those other modules,
which would pretty much destroy the whole point of defining such a
variable. Again, the preferred declaration is "static const int".
o 'static const int' doesn't need an initialisation value! (Presumably this
is then set to zero, but for a mechanism designed to define constant values,
this is a bigger sin that omitting an explicit type.) ('const int' doesn't
need one either, and the value then is undefined.)

You're apparently thinking of block scope. At file scope, "const int"
automatically has static storage duration, so it is initialized to 0 if
not explicitly initialized to anything else, just the same as for
"static const int".
o 'const int' can be set to a runtime value! Presumably such a name cannot
be used as a simple named constant; or can it? The possibilities are
complicated.

The rule in C++, which people are saying should be adopted in C, applies
only to variables initialized with constant expressions. It would not
apply to variables initialized by runtime values.
o 'const int' variables can, in certain circumstances, have their values
changed, so will differ from what the compiler thinks they might be.

Not during their lifetimes, not with defined behavior.
o '[static] const int]' exists now in C, yet cannot be used for dimensioning
arrays or switch case-values. Maybe I missed something in the discussion,
but why is that? And what will change in future as apparently you are not
proposing any new syntax.

The proposal is to adopt C++ rules: a integer const variable initialized
with a integer constant expression is itself an integer constant
expression; as such, it would be usable in those contexts.
o I've just tried using a 'const int' value to define an array, and this
time it worked. Then I realised I was probably creating a VLA. I don't want
to inadvertently construct VLAs!

In C as currently defined, it creates a VLA. With the proposed change,
it would automatically not be a VLA: the standard already says "If the
size is an integer constant expression and the element type has a known
constant size, the array type is not a variable length array type."
(6.7.6.2p4) so no additional changes would be needed to make that true.
So, full of difficulties, so I don't understand your objection to my very
simple proposal, which has few of those problems:

o The name created is *not* a variable

I don't see this as any particular advantage (or disadvantage). In the
unlikely case that you need a const object initialized with the value of
a constant, so you can pass it's address to a function, you can
currently use &const_variable. With your rules, you'd have to use:

const int dummy = constant_value;

and then pass &dummy. It's an absolutely trivial inconvenience, because
there's seldom ever a need to do such things, but I don't see any
corresponding compensating conveniences.
o The initialisation value is mandatory, and *must* be evaluable at
compile-time

C++ has actually adopted this rule for const variables with static
storage duration, for precisely the same reason you've given for your
construct.
You can't propose an essential language feature and then say you need an
elite compiler to implement it properly!

It doesn't require an elite compiler to implement this. This is standard
state-of-the art for C++ compilers, and has been for quite some time.
 
S

Stefan Ram

Stephen Sprunk said:
"Declarations in C must be read in an `inside-out' style that many find
difficult to grasp [Anderson 80]. Sethi [Sethi 81] observed that many of

This is an expression:

*(**(*(*a[1])())[2][3]);

. This is a declaration:

int *(**(*(*a[1])())[2][3]);

. If one can understand the expression, the declaration
should not be much harder. So when one already can read
expressions, one does not have to learn much more to also
understand declaration.
|Had C had a postfix pointer indirection operator

We have. It's »[0]«. *a = a[0]. We also have an outfix: 0[a].
So one has the free choice, between prefix, postfix, and outfix.
 
J

James Kuyper

Possibly. But this is about C.

No, it's about modifications to C. Your proposal is to modify it by
adding a new keyword 'constant'. However, many of us, while recognizing
the validity of some of your complaints about the current C rules,
consider the adoption of C++ rules to be a superior solution, if only
because of improved compatibility with C++.
However, because this is about the C source language, it is less my concern
now as I am moving away from actually having to use it. I just sort of feel
sorry for people who continue to have to battle with such things!

We don't battle with it very often. We use #defines if an integer
constant expression is needed, and otherwise declare const-qualified
object with static storage duration if we want tighter control over type
safety and scope. Under the current rules, we can't do both, but that is
seldom a big problem. I'd like to see the C++ rules adopted, but I'm not
suffering from the fact that this hasn't been done yet.
(If I generate C code, then my named constants get written out as naked
constants in C, completely bypassing the problem. And I am currently moving
away from that too, and generating native code directly, eliminating a lot
of C compiler and language problems, but not all.)

I strongly recommend that approach - you want tighter control over the
generated code than C was ever intended to give you.
 
S

Stefan Ram

James Kuyper said:
It depends upon the scope. It's stupid that C gives two entirely
different meanings to 'static' (there's also a third one that's not
relevant to this question); but it's a historical artifact, and changing
the standard now to cleanly separate the two concepts would break too
much code.

In the English language nearly every word has several different
meanings, often unrelated. So for humans this is very natural.

bat - sporting equipment / winged animal / Windows file type
number - a numeral / more numb

We even have words in English with two meanings, where one meaning
is the opposite of the other:

sanction - permit / penalize
fast - moving rapidly / unmoving

We say »I couldn't care less.«, and everyone understands that it
means »I could care less.«.

In a block, »static int x;« is static, because it remains at
the same address. In file scope, »static int x;« is static,
because it remains in the same file scope, it cannot leave to
other file scopes as with external linkage.
 
S

Stefan Ram

James Kuyper said:
No, it's about modifications to C. Your proposal is to modify it by
adding a new keyword 'constant'. However, many of us, while recognizing
the validity of some of your complaints about the current C rules,
consider the adoption of C++ rules to be a superior solution, if only
because of improved compatibility with C++.

It could even be done without a new keyword. Buy using
»const const« for »constexpr«. This might break only a very
small number of existing programs. Also in English, one
already uses reduplication, for example: »Is it a fruit
salad or a salad salad?«.

Introducing »constexpr« as a keyword might also only break a
very small number of existing C programs.
 
S

Stefan Ram

We say »I couldn't care less.«, and everyone understands that it
means »I could care less.«.

We say »I could care less.«, and everyone understands that
it means »I couldn't care less.«.
 
S

Seungbeom Kim

|Had C had a postfix pointer indirection operator

We have. It's »[0]«. *a = a[0]. We also have an outfix: 0[a].
So one has the free choice, between prefix, postfix, and outfix.

That may help in expressions, albeit no shorter than (* ), but not at
all in declarations, which we have been discussing in this sub-thread.
 
D

David Brown

David Brown said:
On 07/04/14 17:52, BartC wrote:
[On the distinction between an actual constant, a named actual constant,
and
a variable that may or may not have a read-only attribute]
Yes, we should forget about these distinctions. They are not true or
realistic anyway, so why try to pretend that they are?
Remember, a C compiler is /not/ a translator - it does not translate C
source code into assembly. It takes a /description/ or /specification/
of a task, written in the more-or-less carefully defined language C, and
generates object code that will have the same /visible/ effect as the
specified task.

The distinction can be there in the /language/. Clearly not directly in C
because it doesn't have such a language construct, but some people who want
to code would like to have it because it makes certain things obvious and
not a consequence of a whim of a compiler writer.

With C, you can write 5678, but not &5678.

OK...

You can declare a variable xyz, and write as xyz to obtain the value, or as
&xyz to obtain its name (ie. a constant pointer value).

OK...

But note that xyz will not necessarily have an address unless you ask
for one (with &) and make use of that address. Local variables
typically stay in registers or are optimised away completely - they only
naturally have an address if the register set overflows onto the stack
(or if you force them to have an address using &).

And "static const" objects will not have an address or allocated memory
unless you ask for the address, or if a specific memory location gives
the most efficient code.
Why can't I declare abc as a synonym for 5678, but be stopped from writing
&abc? After all I can used #define or enum to declare abc, with some
limitations, and I can't write &abc then either.

I don't know why you would want this. It is not exactly a common typo -
so the way to stop yourself from writing &abc is simply don't write it.
Instead of a simple, logical extension to allow such a declaration,
where it
will be completely obvious what it is and what it can do, you instead
propose using a *variable* for the purpose, which so many issues associated
with it that I hardly know where to start! But I will have a go:

A "const" is not a variable - it is a constant object. So instead of
introducing some sort of new type of constant to the language, I would
rather take the existing const concept and extend it slightly (as it is
in C++) to cover the remaining needs for constants. That is far
simpler, clearer and easier than having a new type of constant - and it
already exists in C++.
o You expect users to apply a 'read-only' attribute to a /variable/, as a
hint to a compiler, so that it can pick up its initialisation value, if
there is one, and treat that as though it is a simple named constant. That
is going around the houses a little!

"const" is not a hint to the compiler about variables - it is a specific
direction that this object will be constant, and will never be changed.
(It is /possible/ to do so using casts, but the result is clearly
undefined behaviour, and cannot be achieved by accident due to the
explicit casts needed, and all the compiler error messages and/or
diagnostic warnings.)


I think you are mixing up the use of "const" in definitions such as
"static const int xyz = 123;", and its use in function arguments
(especially for pointers), such as "size_t strlen(const char* s)".

With the "const" declaration, you are telling the compiler that the
object will /never/ change value after its definition - so it can
happily use the initialisation value directly in code. For externally
defined constants, the compiler does not know the initialisation value -
it is forced to put the constant into memory so that other modules can
access it. But the memory can be read-only memory, and the compiler can
rely on the unchanging nature of the object. For "static const"
objects, the compiler does not have to put it into memory, but can use
the initialisation value directly as a compile-time fixed value. It is
a mere quirk of C language definitions that disallow the use of static
consts for things like array sizes.

When you use the const qualifier in a function argument, like
"strlen(const char* s)", you are telling the compiler that you will not
change anything through the pointer "s". It is not a hint - it is a
promise, and the compiler will hold you to it (with error messages) and
can take advantage of the knowledge that the data will be unchanged.
o It is necessary to use either 'static const int' or 'const int', although
I'm not sure what the difference is between them (that with static
const, it
can only be initialised to a constant expression)?

You are arguing for language extensions, and you don't even understand
the basics of C as it is?

At file level (i.e., not inside a function), "static" objects and
functions are local to the file - they have no external linkage, and
other compilation units cannot refer to them. Unless the objects escape
because you take their address and pass it on to another module through
function calls, then the compiler knows everything about the "static"
object's usage during compilation. In the case of a "static const", if
the initialisation value can be used directly in the code then it does
not need to make a memory location for the constant object. In the case
of functions, the compiler can do more optimisation or inlining because
it does not have to follow standard calling conventions.

Functions and objects that are not "static" have external linkage -
other modules can refer to them by name, so they must follow standard
calling conventions and memory placement (unless you are using link-time
optimisations, of course).

o 'static const int' doesn't need an initialisation value! (Presumably this
is then set to zero, but for a mechanism designed to define constant
values,
this is a bigger sin that omitting an explicit type.) ('const int' doesn't
need one either, and the value then is undefined.)

"const" objects, like variables, are initialised to 0 if you don't give
an explicit initialisation.
o 'const int' can be set to a runtime value! Presumably such a name cannot
be used as a simple named constant; or can it? The possibilities are
complicated.

"const" objects, like variables, must be initialised to compile-time
constants if they are at file scope (or function-local statics). When
they are used locally in functions, they don't exist until the function
is run - of course they can be initialised to any value that is
available when the function is run.
o 'const int' variables can, in certain circumstances, have their values
changed, so will differ from what the compiler thinks they might be.

No, they cannot be changed - any attempt to change them is undefined
behaviour.

(There is such as thing as a "volatile const" object, which is something
that might be changed outside of the program but which is illegal to
change from within the program. Such objects are never compile-time
constants.)
o '[static] const int]' exists now in C, yet cannot be used for
dimensioning
arrays or switch case-values. Maybe I missed something in the discussion,
but why is that? And what will change in future as apparently you are not
proposing any new syntax.

That is correct. I don't know why, other than for historical reasons,
[static] const objects cannot be used for things like array dimensions
in C. Such usage is legal in C++. And yes, I propose that they gain
the C++ features in C.
o I've just tried using a 'const int' value to define an array, and this
time it worked. Then I realised I was probably creating a VLA. I don't want
to inadvertently construct VLAs!

What is wrong with constructing a VLA? Do you know what a VLA actually
/is/? It is only legal in C to use a "const int" for the size of an
array when you are defining a function-local array, and you are correct
that it will be a VLA. But the reason the syntax for a VLA and a
fixed-size array is the same, is that they work in the same way and will
lead to virtually identical code. So it does not matter if the
function-local array is "fixed" size 100 from using a literal (or
#define, or enum), or VLA with a size given by a const or static const
that is initialised to 100.
So, full of difficulties, so I don't understand your objection to my very
simple proposal, which has few of those problems:

So, no difficulties at all - once you understand some basic C concepts.
o The name created is *not* a variable

Nor is a "const" or "static const".
o The initialisation value is mandatory, and *must* be evaluable at
compile-time

The initialisation value for a "const" and "static const" at file scope
must be compile-time constant, and will default to 0 if omitted.
Function-local constants can be initialised any way you like (and any
good compiler will warn you if you forget to initialise it).
o The value will *never* change, and you can never take its address

The value of a "const" or "static const" will /never/ change. You can
take its address if you want, or not if you don't want.
o It can be used to dimension non-VLA arrays, as switch case-values, and
can
be used to construct other such values

That's the only thing missing with C const today - and it should be
easily remedied by copying the feature from C++.
You can't propose an essential language feature and then say you need an
elite compiler to implement it properly!

Yes, I can propose an essential language feature (although I am not
doing so - I am proposing a small but useful addition to an existing
feature) and say good compilers will implement it well. Poor compilers
can easily implement constants as correct but inefficient code.
 
K

Kaz Kylheku

Introducing »constexpr« as a keyword might also only break a
very small number of existing C programs.

Introducing *anything* only breaks those programs which are compiled
with the equivalent of "compiler-name --iso-standard=2014".

The one body of code that needs to be maintained is the header files of
implementations, which are generally expected to work regardless of the dialect
selection.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top