"error C2057: expected constant expression", "error C2466: cannot allocate an array of constant size

Discussion in 'C++' started by hn.ft.pris@gmail.com, Jan 20, 2007.

  1. Guest

    Hi:
    I have the following simple program:

    #include<iostream>
    using namespace std;
    int main(int argc, char* argv[]){

    const double L = 1.234;
    const int T = static_cast<const int>(L);
    int arr[T];
    return 0;
    }

    But I get the error message shown in title. Why doesn't my program
    work? Thanks for help!
     
    , Jan 20, 2007
    #1
    1. Advertising

  2. Re: "error C2057: expected constant expression", "error C2466: cannotallocate an array of constant size 0". Why doesn't my simple program work???

    On 2007-01-20 17:08, wrote:
    > Hi:
    > I have the following simple program:
    >
    > #include<iostream>
    > using namespace std;
    > int main(int argc, char* argv[]){
    >
    > const double L = 1.234;
    > const int T = static_cast<const int>(L);
    > int arr[T];
    > return 0;
    > }
    >
    > But I get the error message shown in title. Why doesn't my program
    > work? Thanks for help!


    Because T is not constant at compile-time, which it needs to be for the
    compiler to know how much space to allocate on the stack. That, of
    course, is not the correct explanation according to the standard but it
    quite nicely describes what is going on. Consider the following code in
    which T is also constant but can wary with every run of the application:

    #include<iostream>

    int main()
    {
    double L;
    std::cin >> L;
    const int T = static_cast<const int>(L);
    return 0;
    }

    --
    Erik Wikström
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Jan 20, 2007
    #2
    1. Advertising

  3. Daniel T. Guest

    Shouldn't this compile?

    wrote:

    > Hi:
    > I have the following simple program:
    >
    > #include<iostream>
    > using namespace std;
    > int main(int argc, char* argv[]) {
    > const double L = 1.234;
    > const int T = static_cast<const int>(L);
    > int arr[T];
    > return 0;
    > }
    >
    > Why doesn't my program work?


    Good question. The code compiled fine for my g++ compiler, but not for
    http://www.comeaucomputing.com/tryitout I have some questions about
    comeau's output:

    > "ComeauTest.c", line 6: warning: type qualifier is meaningless on cast type
    > const int T = static_cast<const int>(L);
    > ^


    What is this? Isn't the 'const' required in the above context?

    > "ComeauTest.c", line 7: error: constant value is not known
    > int arr[T];
    > ^


    Why is that?
     
    Daniel T., Jan 20, 2007
    #3
  4. Kai-Uwe Bux Guest

    Erik Wikström wrote:

    > On 2007-01-20 17:08, wrote:
    >> Hi:
    >> I have the following simple program:
    >>
    >> #include<iostream>
    >> using namespace std;
    >> int main(int argc, char* argv[]){
    >>
    >> const double L = 1.234;
    >> const int T = static_cast<const int>(L);
    >> int arr[T];
    >> return 0;
    >> }
    >>
    >> But I get the error message shown in title. Why doesn't my program
    >> work? Thanks for help!

    >
    > Because T is not constant at compile-time,


    Huh? How is that?

    > which it needs to be for the
    > compiler to know how much space to allocate on the stack. That, of
    > course, is not the correct explanation according to the standard but it
    > quite nicely describes what is going on. Consider the following code in
    > which T is also constant but can wary with every run of the application:
    >
    > #include<iostream>
    >
    > int main()
    > {
    > double L;


    You are cheating in the line above. The OP had:

    const double L = 1.234;
    ^^^^^

    > std::cin >> L;


    With the line of the OP, this would be undefined behavior.

    > const int T = static_cast<const int>(L);
    > return 0;
    > }



    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jan 20, 2007
    #4
  5. Pete Becker Guest

    Re: Shouldn't this compile?

    Daniel T. wrote:
    > wrote:
    >
    >> Hi:
    >> I have the following simple program:
    >>
    >> #include<iostream>
    >> using namespace std;
    >> int main(int argc, char* argv[]) {
    >> const double L = 1.234;
    >> const int T = static_cast<const int>(L);
    >> int arr[T];
    >> return 0;
    >> }
    >>
    >> Why doesn't my program work?

    >
    > Good question. The code compiled fine for my g++ compiler, but not for
    > http://www.comeaucomputing.com/tryitout I have some questions about
    > comeau's output:
    >
    >> "ComeauTest.c", line 6: warning: type qualifier is meaningless on cast type
    >> const int T = static_cast<const int>(L);
    >> ^

    >
    > What is this? Isn't the 'const' required in the above context?
    >
    >> "ComeauTest.c", line 7: error: constant value is not known
    >> int arr[T];
    >> ^

    >
    > Why is that?


    In order for T to be a compile-time constant, it has to have an
    initializer that's a compile-time constant. Floating-point values aren't.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 20, 2007
    #5
  6. Daniel T. Guest

    Re: Shouldn't this compile?

    Pete Becker <> wrote:
    > Daniel T. wrote:
    > > wrote:
    > >
    > > > Hi:
    > > > I have the following simple program:
    > > >
    > > > #include<iostream>
    > > > using namespace std;
    > > > int main(int argc, char* argv[]) {
    > > > const double L = 1.234;
    > > > const int T = static_cast<const int>(L);
    > > > int arr[T];
    > > > return 0;
    > > > }
    > > >
    > > > Why doesn't my program work?

    > >
    > > Good question. The code compiled fine for my g++ compiler, but not for
    > > http://www.comeaucomputing.com/tryitout I have some questions about
    > > comeau's output:
    > >
    > > > "ComeauTest.c", line 6: warning: type qualifier is meaningless on cast type
    > > > const int T = static_cast<const int>(L);
    > > > ^

    > >
    > > What is this? Isn't the 'const' required in the above context?


    What about this warning?

    > > > "ComeauTest.c", line 7: error: constant value is not known
    > > > int arr[T];
    > > > ^

    > >
    > > Why is that?

    >
    > In order for T to be a compile-time constant, it has to have an
    > initializer that's a compile-time constant. Floating-point values aren't.


    I didn't know that. Thanks.
     
    Daniel T., Jan 20, 2007
    #6
  7. Guest

    "Erik Wikström 写é“:
    "
    > On 2007-01-20 17:08, wrote:
    > > Hi:
    > > I have the following simple program:
    > >
    > > #include<iostream>
    > > using namespace std;
    > > int main(int argc, char* argv[]){
    > >
    > > const double L = 1.234;
    > > const int T = static_cast<const int>(L);
    > > int arr[T];
    > > return 0;
    > > }
    > >
    > > But I get the error message shown in title. Why doesn't my program
    > > work? Thanks for help!

    >
    > Because T is not constant at compile-time, which it needs to be for the
    > compiler to know how much space to allocate on the stack. That, of
    > course, is not the correct explanation according to the standard but it
    > quite nicely describes what is going on. Consider the following code in
    > which T is also constant but can wary with every run of the application:
    >
    > #include<iostream>
    >
    > int main()
    > {
    > double L;
    > std::cin >> L;
    > const int T = static_cast<const int>(L);
    > return 0;
    > }
    >
    > --
    > Erik Wikström


    Thanks for help, and here I've made some modification to the program.

    #include<iostream>

    int main()
    {
    #define L 1.234
    #define T static_cast<const int>(L)
    int arr[T];
    return 0;
    }

    Does it mean that now T is a "compile-time determined" variable?
    If it does, then could I suppose that "#define" is expanded and
    calculated at complie-time?
    Does all "#define" perform in a same way?
    Thanks a lot for helping me.
     
    , Jan 21, 2007
    #7
  8. Re: Shouldn't this compile?

    Daniel T. wrote:
    > Pete Becker <> wrote:
    >> Daniel T. wrote:
    >>> wrote:
    >>>
    >>>> Hi:
    >>>> I have the following simple program:
    >>>>
    >>>> #include<iostream>
    >>>> using namespace std;
    >>>> int main(int argc, char* argv[]) {
    >>>> const double L = 1.234;
    >>>> const int T = static_cast<const int>(L);
    >>>> int arr[T];
    >>>> return 0;
    >>>> }
    >>>>
    >>>> Why doesn't my program work?
    >>> Good question. The code compiled fine for my g++ compiler, but not for
    >>> http://www.comeaucomputing.com/tryitout I have some questions about
    >>> comeau's output:
    >>>
    >>>> "ComeauTest.c", line 6: warning: type qualifier is meaningless on cast type
    >>>> const int T = static_cast<const int>(L);
    >>>> ^
    >>> What is this? Isn't the 'const' required in the above context?

    >
    > What about this warning?


    For built-in types, there is no difference between a const rvalue and a
    non-const rvalue. That means that there is no difference between the
    following casts (they both produce an rvalue of type int):

    static_cast<int>(1.234)
    static_cast<const int>(1.234)

    So the const is meaningless in this context.


    --
    Clark S. Cox III
     
    Clark S. Cox III, Jan 21, 2007
    #8
  9. On Jan 20, 8:10 pm, Kai-Uwe Bux <> wrote:
    > Erik Wikström wrote:
    > > On 2007-01-20 17:08, wrote:
    > >> Hi:
    > >> I have the following simple program:

    >
    > >> #include<iostream>
    > >> using namespace std;
    > >> int main(int argc, char* argv[]){

    >
    > >> const double L = 1.234;
    > >> const int T = static_cast<const int>(L);
    > >> int arr[T];
    > >> return 0;
    > >> }

    >
    > >> But I get the error message shown in title. Why doesn't my program
    > >> work? Thanks for help!

    >
    > > Because T is not constant at compile-time,

    >
    > Huh? How is that?


    Because the program have to execute the static_cast before the value of
    T can be determined. And to declare an array on the stack you need to
    know the size of the array at compile-time. Perhaps I was a bit
    unclear, what I meant was that T was not a constant value at
    compile-time.

    > > which it needs to be for the
    > > compiler to know how much space to allocate on the stack. That, of
    > > course, is not the correct explanation according to the standard but it
    > > quite nicely describes what is going on. Consider the following code in
    > > which T is also constant but can wary with every run of the application:

    >
    > > #include<iostream>

    >
    > > int main()
    > > {
    > > double L;

    >
    > You are cheating in the line above. The OP had:
    >
    > const double L = 1.234;
    > ^^^^^


    Yes, but it's the value (and constness) of T that is of interest in
    this problem.

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 22, 2007
    #9
  10. On Jan 21, 10:51 am, wrote:
    > Thanks for help, and here I've made some modification to the program.
    >
    > #include<iostream>
    >
    > int main()
    > {
    > #define L 1.234
    > #define T static_cast<const int>(L)
    > int arr[T];
    > return 0;
    >
    > }
    >
    > Does it mean that now T is a "compile-time determined" variable?


    No, what you have done is to use macros to restructure your code a bit,
    after this has been through the pre-processor this is what you'll get:

    #include<iostream>

    int main()
    {
    int arr[static_cast<const int>(1.234)];
    return 0;
    }

    > If it does, then could I suppose that "#define" is expanded and
    > calculated at compile-time?


    They are expanded, yes, but not calculated. Or rather the static_cast
    is not evaluated until runtime, which is to late since the size of the
    array needs to be known at compile-time.

    > Does all "#define" perform in a same way?


    All defines are expanded by the pre-processor, but that is all, if you
    want code evaluated at compile-time you can do some things with
    templates, but I don't think that's what you want.

    What you can do is to allocate the array on the heap:

    int main()
    {
    int* arr = new int[static_cast<const int>(1.234)];
    delete[] arr; // don't forget this when you are done
    return 0;
    }

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Jan 22, 2007
    #10
  11. Kai-Uwe Bux Guest

    Erik Wikström wrote:

    > On Jan 20, 8:10 pm, Kai-Uwe Bux <> wrote:
    >> Erik Wikström wrote:
    >> > On 2007-01-20 17:08, wrote:
    >> >> Hi:
    >> >> I have the following simple program:

    >>
    >> >> #include<iostream>
    >> >> using namespace std;
    >> >> int main(int argc, char* argv[]){

    >>
    >> >> const double L = 1.234;
    >> >> const int T = static_cast<const int>(L);
    >> >> int arr[T];
    >> >> return 0;
    >> >> }

    >>
    >> >> But I get the error message shown in title. Why doesn't my program
    >> >> work? Thanks for help!

    >>
    >> > Because T is not constant at compile-time,

    >>
    >> Huh? How is that?

    >
    > Because the program have to execute the static_cast before the value of
    > T can be determined. And to declare an array on the stack you need to
    > know the size of the array at compile-time. Perhaps I was a bit
    > unclear, what I meant was that T was not a constant value at
    > compile-time.


    The static_cast explanation is wanting:

    unsigned char const c = 'c';
    unsigned int const i = static_cast<int>( c );

    typedef char array ;

    int main ( void ) {
    array A;
    }

    The above compiles fine and is, as far as I can tell standard conforming
    even though it uses a static cast. The crux of the matter seems to be that
    non-integer arithmetic expressions do not qualify as compile time constants
    (allowing the compiler and the target processor to differ in their opinion
    on how to approximate pi properly).

    >
    >> > which it needs to be for the
    >> > compiler to know how much space to allocate on the stack.

    [non-disputed facts snipped]


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jan 22, 2007
    #11
  12. Guest

    "Erik Wikström 写é“:
    "
    > On Jan 21, 10:51 am, wrote:
    > > Thanks for help, and here I've made some modification to the program.
    > >
    > > #include<iostream>
    > >
    > > int main()
    > > {
    > > #define L 1.234
    > > #define T static_cast<const int>(L)
    > > int arr[T];
    > > return 0;
    > >
    > > }
    > >
    > > Does it mean that now T is a "compile-time determined" variable?

    >
    > No, what you have done is to use macros to restructure your code a bit,
    > after this has been through the pre-processor this is what you'll get:
    >
    > #include<iostream>
    >
    > int main()
    > {
    > int arr[static_cast<const int>(1.234)];
    > return 0;
    > }
    >


    Yes, I get it.
    But how to explain the following odd behavior of MS VS8:

    int main(int argc, char** argv){
    #define L 1.234
    #define T static_cast<int>(L)
    int arr[T];
    arr[0] = 1;
    cout << arr[0] << endl;
    return 0;
    }
    Fine, without any warnings or errors.

    int main(int argc, char** argv){
    double L = 1.234;
    int T = static_cast<int>(L);
    int arr[T];
    arr[0] = 1;
    cout << arr[0] << endl;
    return 0;
    }
    error C2057: expected constant expression; error C2466: cannot allocate
    an array of constant size 0, on MS VS8
    while gcc 3.4.2 approve it.

    > > If it does, then could I suppose that "#define" is expanded and
    > > calculated at compile-time?

    >
    > They are expanded, yes, but not calculated. Or rather the static_cast
    > is not evaluated until runtime, which is to late since the size of the
    > array needs to be known at compile-time.
    >
    > > Does all "#define" perform in a same way?

    >
    > All defines are expanded by the pre-processor, but that is all, if you
    > want code evaluated at compile-time you can do some things with
    > templates, but I don't think that's what you want.
    >
    > What you can do is to allocate the array on the heap:
    >
    > int main()
    > {
    > int* arr = new int[static_cast<const int>(1.234)];
    > delete[] arr; // don't forget this when you are done
    > return 0;
    > }
    >
    > --
    > Erik Wikström
     
    , Jan 22, 2007
    #12
  13. Greg Guest

    Kai-Uwe Bux wrote:
    >
    > unsigned char const c = 'c';
    > unsigned int const i = static_cast<int>( c );
    >
    > typedef char array ;
    >
    > int main ( void ) {
    > array A;
    > }
    >
    > The above compiles fine and is, as far as I can tell standard conforming
    > even though it uses a static cast. The crux of the matter seems to be that
    > non-integer arithmetic expressions do not qualify as compile time constants
    > (allowing the compiler and the target processor to differ in their opinion
    > on how to approximate pi properly).


    Although this program is legal:

    unsigned int const i = 3.14159;

    typedef char array;

    int main()
    {
    array A;
    }

    Greg
     
    Greg, Jan 22, 2007
    #13
  14. Kai-Uwe Bux Guest

    Greg wrote:

    >
    > Kai-Uwe Bux wrote:
    >>
    >> unsigned char const c = 'c';
    >> unsigned int const i = static_cast<int>( c );
    >>
    >> typedef char array ;
    >>
    >> int main ( void ) {
    >> array A;
    >> }
    >>
    >> The above compiles fine and is, as far as I can tell standard conforming
    >> even though it uses a static cast. The crux of the matter seems to be
    >> that non-integer arithmetic expressions do not qualify as compile time
    >> constants (allowing the compiler and the target processor to differ in
    >> their opinion on how to approximate pi properly).

    >
    > Although this program is legal:
    >
    > unsigned int const i = 3.14159;
    >
    > typedef char array;
    >
    > int main()
    > {
    > array A;
    > }


    This is making me dizzy. Here is what the standard has to say [5.19/1]:

    [...] An integral constant-expression can involve only literals (2.13),
    enumerators, const variables or static data members of integral or
    enumeration types initialized with constant expressions (8.5), non-type
    template parameters of integral or enumeration types, and sizeof
    expressions. Floating literals (2.13.3) can appear only if they are cast
    to integral or enumeration types. Only type conversions to integral or
    enumeration types can be used. In particular, except in sizeof
    expressions, functions, class objects, pointers, or references shall not
    be used, and assignment, increment, decrement, function-call, or comma
    operators shall not be used.

    So, it appears that the only legal way that a float can make it into an
    integral constant-expression is as a floating literal converted to an
    integral or enumeration type. In particular, const variables of floating
    point types do not qualify even if they are initialized with a (floating
    point) constant-expression.

    Makes you wonder what the rational might be.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jan 22, 2007
    #14
    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. Roedy Green
    Replies:
    3
    Views:
    3,290
    Roedy Green
    Aug 14, 2003
  2. rveloso

    popen cannot allocate memory

    rveloso, Apr 4, 2006, in forum: C Programming
    Replies:
    1
    Views:
    1,208
    Keith Thompson
    Apr 4, 2006
  3. valerio
    Replies:
    3
    Views:
    383
  4. saneman

    Cannot allocate array

    saneman, Aug 2, 2008, in forum: C++
    Replies:
    2
    Views:
    351
    Juha Nieminen
    Aug 2, 2008
  5. SAUHING LEE

    dynamically allocate array size using malloc

    SAUHING LEE, Dec 5, 2008, in forum: C Programming
    Replies:
    7
    Views:
    3,310
Loading...

Share This Page