const int not constant expression?

Discussion in 'C++' started by William Payne, Aug 26, 2003.

  1. Hello, in my application (which spans approximately 20 source files and a
    2-3 thousand lines) I have a few global varialbes, variables that never
    change their values. One of them is declared like this:
    /* globals.h */
    extern const int g_tray_icon_callback;

    /* globals.cpp */
    const int g_tray_icon_callback = 4711;

    Now, when I tried to use that variable as a case label in switch statement,
    I got:
    main_dialog_procedure.cpp:64: error: case label does not reduce to an
    integer
    constant

    So, I replaced the const int with a #define and it compiles, but why can't I
    use a const int? I thought const would be const, but I guess not...

    // William Payne
    William Payne, Aug 26, 2003
    #1
    1. Advertising

  2. William Payne wrote:
    > Hello, in my application (which spans approximately 20 source files and a
    > 2-3 thousand lines) I have a few global varialbes, variables that never
    > change their values. One of them is declared like this:
    > /* globals.h */
    > extern const int g_tray_icon_callback;
    >
    > /* globals.cpp */
    > const int g_tray_icon_callback = 4711;
    >
    > Now, when I tried to use that variable as a case label in switch statement,
    > I got:
    > main_dialog_procedure.cpp:64: error: case label does not reduce to an
    > integer
    > constant
    >
    > So, I replaced the const int with a #define and it compiles, but why can't I
    > use a const int? I thought const would be const, but I guess not...


    You can. But in order to be able to use this 'const int' variable in a
    case label, you have to declare it _with_ _initilaizer_ in the same
    translation unit where your 'switch' is located.

    Just put

    const int g_tray_icon_callback = 4711;

    into your 'globals.h' file and remove the definition from 'globals.cpp'.

    --
    Best regards,
    Andrey Tarasevich
    Brainbench C and C++ Programming MVP
    Andrey Tarasevich, Aug 26, 2003
    #2
    1. Advertising

  3. William Payne

    ES Kim Guest

    "William Payne" <> wrote in message
    news:bieaqv$3n0$...
    > Hello, in my application (which spans approximately 20 source files and a
    > 2-3 thousand lines) I have a few global varialbes, variables that never
    > change their values. One of them is declared like this:
    > /* globals.h */
    > extern const int g_tray_icon_callback;
    >
    > /* globals.cpp */
    > const int g_tray_icon_callback = 4711;
    >
    > Now, when I tried to use that variable as a case label in switch statement,
    > I got:
    > main_dialog_procedure.cpp:64: error: case label does not reduce to an
    > integer
    > constant
    >
    > So, I replaced the const int with a #define and it compiles, but why can't I
    > use a const int? I thought const would be const, but I guess not...
    >
    > // William Payne
    >
    >


    It's because g_tray_icon_callback defined in globals.cpp has
    internal linkage. const objects have internal linkage by default.
    Andrey provided a solution. Another is to make it have external
    linkage.

    /* globals.cpp */
    extern const int g_tray_icon_callback = 4711;

    --
    ES Kim
    ES Kim, Aug 26, 2003
    #3
  4. "Andrey Tarasevich" <> wrote in message
    news:...
    > William Payne wrote:
    > > Hello, in my application (which spans approximately 20 source files and

    a
    > > 2-3 thousand lines) I have a few global varialbes, variables that never
    > > change their values. One of them is declared like this:
    > > /* globals.h */
    > > extern const int g_tray_icon_callback;
    > >
    > > /* globals.cpp */
    > > const int g_tray_icon_callback = 4711;
    > >
    > > Now, when I tried to use that variable as a case label in switch

    statement,
    > > I got:
    > > main_dialog_procedure.cpp:64: error: case label does not reduce to an
    > > integer
    > > constant
    > >
    > > So, I replaced the const int with a #define and it compiles, but why

    can't I
    > > use a const int? I thought const would be const, but I guess not...

    >
    > You can. But in order to be able to use this 'const int' variable in a
    > case label, you have to declare it _with_ _initilaizer_ in the same
    > translation unit where your 'switch' is located.
    >
    > Just put
    >
    > const int g_tray_icon_callback = 4711;
    >
    > into your 'globals.h' file and remove the definition from 'globals.cpp'.
    >
    > --
    > Best regards,
    > Andrey Tarasevich
    > Brainbench C and C++ Programming MVP
    >


    Thank you for the help

    // William Payne
    William Payne, Aug 26, 2003
    #4
  5. ES Kim wrote:
    > "William Payne" <> wrote in message
    > news:bieaqv$3n0$...
    >> Hello, in my application (which spans approximately 20 source files and a
    >> 2-3 thousand lines) I have a few global varialbes, variables that never
    >> change their values. One of them is declared like this:
    >> /* globals.h */
    >> extern const int g_tray_icon_callback;
    >>
    >> /* globals.cpp */
    >> const int g_tray_icon_callback = 4711;
    >>
    >> Now, when I tried to use that variable as a case label in switch statement,
    >> I got:
    >> main_dialog_procedure.cpp:64: error: case label does not reduce to an
    >> integer
    >> constant
    >>
    >> So, I replaced the const int with a #define and it compiles, but why can't I
    >> use a const int? I thought const would be const, but I guess not...
    >>
    >> // William Payne
    >>
    >>

    >
    > It's because g_tray_icon_callback defined in globals.cpp has
    > internal linkage.


    That's not true. Provided the declaration of 'g_tray_icon_callback' in
    'globals.h' is visible in 'globals.cpp' (i.e. 'globals.h' is included
    into 'globals.cpp'), constant object 'g_tray_icon_callback' has external
    linkage since it is declared with 'extern' specifier.

    > const objects have internal linkage by default.


    Yes. But in this case it is not "by default". 'g_tray_icon_callback' is
    declared in 'globals.cpp' with explicit 'extern' specifier.

    > Andrey provided a solution.


    My solution actually changes the linkage of 'g_tray_icon_callback' to
    internal, meaning that each translation unit will get its own completely
    independent instance of 'g_tray_icon_callback'.

    > Another is to make it have external
    > linkage.
    >
    > /* globals.cpp */
    > extern const int g_tray_icon_callback = 4711;


    That's not necessary. The declaration in 'globals.h' is sufficient to
    change the linkage of this object.

    The whole point of my solution is to make the initializer ('= 4711')
    visible in all translation units. Your solution doesn't do that, which
    means that it won't solve anything.

    --
    Best regards,
    Andrey Tarasevich
    Brainbench C and C++ Programming MVP
    Andrey Tarasevich, Aug 26, 2003
    #5
  6. William Payne

    ES Kim Guest

    "Andrey Tarasevich" <> wrote in message
    news:...

    [snip]

    You're right. Thanks for your concrete explanation.

    --
    ES Kim
    ES Kim, Aug 26, 2003
    #6
    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. Timo Freiberger
    Replies:
    3
    Views:
    919
    Bob Hairgrove
    Oct 30, 2004
  2. Replies:
    11
    Views:
    1,083
  3. jaime
    Replies:
    4
    Views:
    685
    Keith Thompson
    Jun 16, 2007
  4. Javier
    Replies:
    2
    Views:
    533
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,082
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page