tags:

views:

324

answers:

4

Why doesn't this C program compile? What is wrong with this?

I have tried it on wxDevC++ and Turbo C++ 3.0.

Main.c

#include<stdio.h>
#include<conio.h>

const int SIZE = 5;

int main(int argc, char ** argv)
{    
    char array[SIZE] = {'A', 'B', 'C', 'D', 'E'};

    printf("Array elements are,\n");
    int i=0;

    for(i=0 ; i<SIZE ; ++i)
    {
        printf("%c  ", array[i]);
    }

    getch();

    return 0;
}

Error Messages on the both of the compilers are similar.

f:\_Source-Codes\main.c In function `main':

8 f:\_Source-Codes\main.c variable-sized object may not be initialized
+8  A: 

if the compiler is treating it as a '.c' file, the int i declaration needs to before any executable lines, speficically, before the printf.

EDIT, now that you showed the error message:

The compiler does not consider SIZE as a constant when compiling main. You could use #define SIZE 5 as a work-around.

According to K&R 2nd Ed. :

"The purpose of const is to announce objects that may be placed in read-only memory. ... Except that it should diagnose explicit attempts to change const objects, a compiler may ignore [the const] qualifier".

So declaring const int SIZE = 5 does not make SIZE a constant-expression, which is what an array size specifier requires.

AShelly
Yes. But why doesn't const work? What does ANSI standard says?
JMSA
Correct, the declaration has to proceed the method.
Jamie Keeling
maybe because Turbo C++ 3.0 is almost 20 years old
fuzzy lollipop
@fuzzy lollipop, OK but I have also tested it on wxDevC++ and VS2008.
JMSA
AndreyT
AShelly
+3  A: 

try this:

char array[] = {'A', 'B', 'C', 'D', 'E'};
Andrey
I know the solution. Just tell me why doesn't it work?
JMSA
@overslacked, This is not true. The size depends first on the constant specified. `char array[2] = {'a','b','c'};` generates an error. `char array[3] = {'a','b'};` generates a 3 element array. The size is only infered from the initializer list if the `[]`s are empty.
AShelly
+5  A: 

Try replacing

const int SIZE = 5;

with

#define SIZE 5

Most C compilers don't allow declaring static arrays whose sizes are contained in variables (i.e. the array size is determined at runtime).

MAK
Most? What compilers do allow declaring *static* arrays "whose sizes are contained in variables"?
AndreyT
@AndreyT: Just trying to be safe rather than sorry.
MAK
+14  A: 

Array size in C89/90 language must be specified by an integral constant expression (in general true for C99 as well). A const int object in C is not a constant expression, which is why you can't use it to specify array size. Note: this is one prominent difference between C and C++.

In C language the term constant refers to literal constants, i.e. 5, 10.2, 0xFF, 'a' and so on (enum constants are also constants, to be precise). const int object, once again, is not a constant in C and cannot be used to build constant expressions.

If you want to pre-declare a named constant to be used as array size in C, you have to use either #define or enum. The same applies to case labels, bit-field sizes and every other context requiring a constant expression.

See this for more details.

AndreyT
Is this allowed in C++? If I did `const int SIZE = someFunction();`, the compiler wouldn't know at compile-time how much stack-space is needed for `char array[SIZE]`...
BlueRaja - Danny Pflughoeft
@BlueRaja: In C++ constant expressions can use `const` objects *initialized with constant expressions*. In your case, your `const` object is not initialized with a constant expression, which is why it is by itself not a constant.
AndreyT
@AndreyT, Then what is the use of const-keyword in C?
JMSA
@Andrey: any links as to what constitutes a *constant expression*? What if someFunction() is defined as `const int someFunction() { return 5; }` - would SIZE then be considered initialized with a constant expression?
BlueRaja - Danny Pflughoeft
@JMSA: `const` only means that you can't change the value of the variable later - the initial value itself may not be a constant expression.@BlueRaja: I guess that depends on whether the compiler decides to expand `someFunction` inline.
casablanca
@JMSA: `const` keyword in C is used to declare objects that should not be changed at run-time (and to declare const-qualified access paths to objects). It doesn't introduce compile-time constants, which is why it has significantly more limited use in C than in C++.
AndreyT
@BlueRaja: No. In todays C++ the result of a function call is never a constant expression, regardless of whether it is inline or not. In future C++ standard a new keyword is coming up (`constexpr` or something like that) that would allow you to declare functions that can be used in constant expressions. This is exactly what would apply to your function.
AndreyT
@BlueRaja: As for the links... The notion of *constant expression* is defined in 6.6 in C99 standard. *Integral* constant expression is defined in 6.6.6. You can download document `n1256`, if you don't have a copy already: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
AndreyT