Array sizes and const

Discussion in 'C Programming' started by Les Cargill, Jun 2, 2012.

  1. Les Cargill

    Les Cargill Guest

    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
     
    Les Cargill, Jun 2, 2012
    #1
    1. Advertising

  2. Les Cargill

    Ian Collins Guest

    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
     
    Ian Collins, Jun 2, 2012
    #2
    1. Advertising

  3. Les Cargill

    Eric Sosman Guest

    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
    d
     
    Eric Sosman, Jun 2, 2012
    #3
  4. Les Cargill

    Les Cargill Guest

    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
     
    Les Cargill, Jun 2, 2012
    #4
  5. Les Cargill

    Les Cargill Guest

    <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
     
    Les Cargill, Jun 2, 2012
    #5
  6. Les Cargill <> 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) <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"
     
    Keith Thompson, Jun 2, 2012
    #6
  7. Les Cargill

    Les Cargill Guest

    Keith Thompson wrote:
    > Les Cargill<> 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
     
    Les Cargill, Jun 2, 2012
    #7
  8. Les Cargill

    Nobody Guest

    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.
     
    Nobody, Jun 2, 2012
    #8
  9. Les Cargill

    Ian Collins Guest

    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
     
    Ian Collins, Jun 2, 2012
    #9
  10. Les Cargill

    James Kuyper Guest

    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
     
    James Kuyper, Jun 3, 2012
    #10
  11. Les Cargill <> 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) <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"
     
    Keith Thompson, Jun 3, 2012
    #11
  12. Les Cargill

    Les Cargill Guest

    Keith Thompson wrote:
    > Les Cargill<> 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
     
    Les Cargill, Jun 3, 2012
    #12
  13. Les Cargill

    BartC Guest

    "Les Cargill" <> wrote in message
    news:jqe303$id9$...
    > 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
     
    BartC, Jun 3, 2012
    #13
  14. Les Cargill

    Nobody Guest

    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.
     
    Nobody, Jun 3, 2012
    #14
  15. בת×ריך ×™×•× ×¨×שון, 3 ביוני 2012 02:11:15 UTC+1, מ×ת James Kuyper:
    > 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.
    >

    I never use it. Part of the reason is that whilst int member(const FOO *obj) is clear enough in intention, in fact the constness of obj does not extend to its members. Another is the const-poisoning problem. You have to use const consistently, or you end up needing to pass a const pointer to a non-const subroutine which doesn't in fact alter the data.
    Then C++ added mutable. This makes a member of a const class non-const. Thefact that mutable was considered necessary is an argument against const.

    But the main reason is simply visual clutter. You want to be able to see what a function does at a glance.
     
    Malcolm McLean, Jun 3, 2012
    #15
  16. Les Cargill

    James Kuyper Guest

    On 06/03/2012 10:39 AM, Malcolm McLean wrote:
    ....
    > does not extend to its members. Another is the const-poisoning
    > problem. You have to use const consistently, or you end up needing to
    > pass a const pointer to a non-const subroutine which doesn't in fact
    > alter the data.


    I don't see that as a problem. Forcing consistent use of const is good
    mental discipline; the casts that are needed to interface with libraries
    that don't use it correctly helps document those library's faults.
    --
    James Kuyper
     
    James Kuyper, Jun 3, 2012
    #16
  17. Malcolm McLean <> writes:

    > בת×ריך ×™×•× ×¨×שון, 3 ביוני 2012 02:11:15 UTC+1, מ×ת James Kuyper:
    >> 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.
    >>

    > I never use it. Part of the reason is that whilst int member(const FOO
    > *obj) is clear enough in intention, in fact the constness of obj does
    > not extend to its members.


    Can you say what you mean by this? It contradicts what I thought was
    the case (assuming you meant the members of *obj).

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Jun 3, 2012
    #17
  18. "BartC" <> 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) <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"
     
    Keith Thompson, Jun 3, 2012
    #18
  19. Les Cargill

    Ian Collins Guest

    On 06/ 4/12 02:39 AM, Malcolm McLean wrote:
    > בת×ריך ×™×•× ×¨×שון, 3 ביוני 2012 02:11:15 UTC+1, מ×ת James Kuyper:
    >> 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.


    Please please wrap your lines!

    > I never use it. Part of the reason is that whilst int member(const FOO *obj)
    > is clear enough in intention, in fact the constness of obj does not extend
    > to its members.


    Eh? What if FOO is in read only memory?

    > Another is the const-poisoning problem. You have to use const consistently,
    > or you end up needing to pass a const pointer to a non-const subroutine
    > which doesn't in fact alter the data.


    So good coding discipline is bad?

    > Then C++ added mutable. This makes a member of a const class non-const.
    > The fact that mutable was considered necessary is an argument against

    const.

    Mutable is rarely used in C++. Most of the cases in my own code are for
    internal state variables.

    > But the main reason is simply visual clutter. You want to be able to see
    > what a function does at a glance.


    Isn't whether the function modifies its arguments one of the most
    important things you want to see at a glance?

    --
    Ian Collins
     
    Ian Collins, Jun 3, 2012
    #19
  20. Ben Bacarisse <> writes:
    > Malcolm McLean <> writes:
    >> בת×ריך ×™×•× ×¨×שון, 3 ביוני 2012 02:11:15 UTC+1, מ×ת James Kuyper:
    >>> 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.
    >>>

    >> I never use it. Part of the reason is that whilst int member(const FOO
    >> *obj) is clear enough in intention, in fact the constness of obj does
    >> not extend to its members.

    >
    > Can you say what you mean by this? It contradicts what I thought was
    > the case (assuming you meant the members of *obj).
    >
    > <snip>


    Agreed.

    typedef struct foo {
    int x;
    } FOO;

    int member(const FOO *obj) {
    obj->x = 42;
    return 43;
    }

    int main(void) {
    FOO foo_obj;
    int m = member(&foo_obj);
    return 0;
    }

    c.c: In function ‘member’:
    c.c:6:5: error: assignment of member ‘x’ in read-only object

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Jun 3, 2012
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    11
    Views:
    1,143
  2. Javier
    Replies:
    2
    Views:
    603
    James Kanze
    Sep 4, 2007
  3. 0m
    Replies:
    26
    Views:
    1,159
    Tim Rentsch
    Nov 10, 2008
  4. fungus
    Replies:
    13
    Views:
    927
    fungus
    Oct 31, 2008
  5. Replies:
    2
    Views:
    552
    Andrew Koenig
    Feb 9, 2009
Loading...

Share This Page