extern const variable in case label

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christian Meier

    extern const variable in case label

    Hello NG

    I have the following code:


    file1.h:

    static const int iValue = 5;

    <EOF>


    file2.cpp

    #include <iostream>
    #include "file1.h"

    int main(int args, char* argv[])
    {
    switch(args) {
    case iValue:
    std::cout << "Hello\n";
    }
    }

    <EOF>



    This works fine as the value of the constant "iValue" is known when
    compiling the main()-function in file2.cpp.
    I have some more cpp-files which include file1.h. Therefore I have a copy of
    "iValue" in each translation unit as it has internal linkage. In the
    executable which is made with these object files (translation units) I have
    several copies of that variable; all having the same value.

    Now, I would like to change the linkage of "iValue" to extern so that there
    is only one symbol for this constant in my executable.
    When I change the keyword "static" to "extern" I have the problem that the
    symbol is more than once defined in my executable.
    When I only declare the variable "iValue" in file1.h with external linkage
    ("extern const int iValue;") and define it in a new file called file1.cpp
    ("extern const iValue = 5;"), then I have no problem with multiple
    definitions but I have a new problem in my function main() because the value
    of "iValue" is not known when compiling file2.cpp.

    Do you have any suggestions how I can compile all my code without having
    more than one symbol for "iValue" in my program? Or is it not possible what
    I am trying to reach?


    Thanks for all your answers in advance,
    Chris


  • thomas

    #2
    Re: extern const variable in case label

    On Oct 2, 5:23 pm, "Christian Meier" <chris@no_spam. comwrote:
    Hello NG
    >
    I have the following code:
    >
    file1.h:
    >
    static const int iValue = 5;
    >
    <EOF>
    >
    file2.cpp
    >
    #include <iostream>
    #include "file1.h"
    >
    int main(int args, char* argv[])
    {
        switch(args) {
        case iValue:
            std::cout << "Hello\n";
        }
    >
    }
    >
    <EOF>
    >
    This works fine as the value of the constant "iValue" is known when
    compiling the main()-function in file2.cpp.
    I have some more cpp-files which include file1.h. Therefore I have a copyof
    "iValue" in each translation unit as it has internal linkage. In the
    executable which is made with these object files (translation units) I have
    several copies of that variable; all having the same value.
    >
    Now, I would like to change the linkage of "iValue" to extern so that there
    is only one symbol for this constant in my executable.
    When I change the keyword "static" to "extern" I have the problem that the
    symbol is more than once defined in my executable.
    When I only declare the variable "iValue" in file1.h with external linkage
    ("extern const int iValue;") and define it in a new file called file1.cpp
    ("extern const iValue = 5;"), then I have no problem with multiple
    definitions but I have a new problem in my function main() because the value
    of "iValue" is not known when compiling file2.cpp.
    >
    Do you have any suggestions how I can compile all my code without having
    more than one symbol for "iValue" in my program? Or is it not possible what
    I am trying to reach?
    >
    Thanks for all your answers in advance,
    Chris
    well. I think you should keep in mind that the case value can only be
    constant integral values.

    Comment

    • Christian Meier

      #3
      Re: extern const variable in case label

      well. I think you should keep in mind that the case value can only be
      constant integral values.
      What do you exactly mean with this? Isn't "extern const int iValue" a
      constant integral value?


      Comment

      • Martin Eisenberg

        #4
        Re: extern const variable in case label

        Christian Meier wrote:
        Do you have any suggestions how I can compile all my code
        without having more than one symbol for "iValue" in my program?
        Or is it not possible what I am trying to reach?
        How about this?

        enum { iValue = int(5) };


        Martin

        --
        Quidquid latine scriptum est, altum videtur.

        Comment

        • Christian Meier

          #5
          Re: extern const variable in case label

          "Martin Eisenberg" <martin.eisenbe rg@udo.eduwrote :
          Christian Meier wrote:
          >
          >Do you have any suggestions how I can compile all my code
          >without having more than one symbol for "iValue" in my program?
          >Or is it not possible what I am trying to reach?
          >
          How about this?
          >
          enum { iValue = int(5) };
          >
          Thanks for your answer!
          Ok, you're right, that could be a solution for "int".
          To tell a bit more of the truth, I have these constants for quite all
          built-in types (double, long int, short...) and IIRC enum values must have
          type int.


          Comment

          • James Kanze

            #6
            Re: extern const variable in case label

            On Oct 2, 11:23 am, "Christian Meier" <chris@no_spam. comwrote:
            I have the following code:
            file1.h:
            static const int iValue = 5;
            <EOF>
            file2.cpp
            #include <iostream>
            #include "file1.h"
            int main(int args, char* argv[])
            {
            switch(args) {
            case iValue:
            std::cout << "Hello\n";
            }
            }
            <EOF>
            This works fine as the value of the constant "iValue" is known
            when compiling the main()-function in file2.cpp.
            I have some more cpp-files which include file1.h. Therefore I
            have a copy of "iValue" in each translation unit as it has
            internal linkage. In the executable which is made with these
            object files (translation units) I have several copies of that
            variable; all having the same value.
            Maybe. Maybe not.
            Now, I would like to change the linkage of "iValue" to extern
            so that there is only one symbol for this constant in my
            executable. When I change the keyword "static" to "extern" I
            have the problem that the symbol is more than once defined in
            my executable. When I only declare the variable "iValue" in
            file1.h with external linkage ("extern const int iValue;") and
            define it in a new file called file1.cpp ("extern const iValue
            = 5;"), then I have no problem with multiple definitions but I
            have a new problem in my function main() because the value of
            "iValue" is not known when compiling file2.cpp.
            Do you have any suggestions how I can compile all my code
            without having more than one symbol for "iValue" in my
            program? Or is it not possible what I am trying to reach?
            Do you have some valid reason for wanting iValue to have the
            same address in every translation unit? It seems strange to me
            to give an int identity, especially if you're not going to
            change it. And otherwise, what's the problem with what you have
            written initially?

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            • Christian Meier

              #7
              Re: extern const variable in case label

              "James Kanze" <james.kanze@gm ail.comwrote:
              Do you have some valid reason for wanting iValue to have the
              same address in every translation unit?
              No...
              It seems strange to me to give an int identity, especially if you're not
              going to
              change it.
              What else would you use for a global integer constant? Would you use a
              #define?
              And otherwise, what's the problem with what you have written initially?
              With my compiler and linker I have these symbols over 10 000 times in my
              executable and I was able to reduce the program size a bit with changing
              these constants to extern which are not used in case labels.


              Comment

              • James Kanze

                #8
                Re: extern const variable in case label

                On Oct 2, 5:33 pm, "Christian Meier" <chris@no_spam. comwrote:
                "James Kanze" <james.ka...@gm ail.comwrote:
                Do you have some valid reason for wanting iValue to have the
                same address in every translation unit?
                No...
                It seems strange to me to give an int identity, especially
                if you're not going to change it.
                What else would you use for a global integer constant? Would you use a
                #define?
                No. Just a static int const, like you did originally.
                And otherwise, what's the problem with what you have written
                initially?
                With my compiler and linker I have these symbols over 10 000
                times in my executable and I was able to reduce the program
                size a bit with changing these constants to extern which are
                not used in case labels.
                That is strange. I've yet to see a compiler where they'd take
                any space at all, as long as their address wasn't taken.

                --
                James Kanze (GABI Software) email:james.kan ze@gmail.com
                Conseils en informatique orientée objet/
                Beratung in objektorientier ter Datenverarbeitu ng
                9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                Comment

                • Barry

                  #9
                  Re: extern const variable in case label

                  On 10ÔÂ2ÈÕ, ÏÂÎç5ʱ23·Ö, "Christian Meier" <chris@no_spam. comwrote:
                  Hello NG
                  >
                  I have the following code:
                  >
                  file1.h:
                  >
                  static const int iValue = 5;
                  >
                  <EOF>
                  >
                  file2.cpp
                  >
                  #include <iostream>
                  #include "file1.h"
                  >
                  int main(int args, char* argv[])
                  {
                  switch(args) {
                  case iValue:
                  std::cout << "Hello\n";
                  }
                  >
                  }
                  >
                  <EOF>
                  >
                  This works fine as the value of the constant "iValue" is known when
                  compiling the main()-function in file2.cpp.
                  I have some more cpp-files which include file1.h. Therefore I have a copyof
                  "iValue" in each translation unit as it has internal linkage. In the
                  executable which is made with these object files (translation units) I have
                  several copies of that variable; all having the same value.
                  >
                  Now, I would like to change the linkage of "iValue" to extern so that there
                  is only one symbol for this constant in my executable.
                  When I change the keyword "static" to "extern" I have the problem that the
                  symbol is more than once defined in my executable.
                  When I only declare the variable "iValue" in file1.h with external linkage
                  ("extern const int iValue;") and define it in a new file called file1.cpp
                  ("extern const iValue = 5;"), then I have no problem with multiple
                  definitions but I have a new problem in my function main() because the value
                  of "iValue" is not known when compiling file2.cpp.
                  >
                  Do you have any suggestions how I can compile all my code without having
                  more than one symbol for "iValue" in my program? Or is it not possible what
                  I am trying to reach?
                  >
                  IIRC, just

                  const int iValue = 5;

                  no 'static', no 'extern'

                  --
                  Best Regards
                  Barry

                  Comment

                  • Christian Meier

                    #10
                    Re: extern const variable in case label

                    "James Kanze" <james.kanze@gm ail.comwrote:
                    It seems strange to me to give an int identity, especially
                    if you're not going to change it.
                    What else would you use for a global integer constant? Would you use a
                    #define?
                    No. Just a static int const, like you did originally.
                    Ok thanks. Probably I will not change the code so it remains a static const
                    int.

                    With my compiler and linker I have these symbols over 10 000
                    times in my executable and I was able to reduce the program
                    size a bit with changing these constants to extern which are
                    not used in case labels.
                    That is strange. I've yet to see a compiler where they'd take
                    any space at all, as long as their address wasn't taken.
                    Eventually my assumption was wrong about the more than 10 000 symbols for
                    this variable.... And I have not checked whether the address is taken.


                    <Offtopic: UNIX Commands and Compiler version>

                    But the command "nm MyExecutable | grep iValue | wc -l" has the output
                    "11059" at this moment.
                    We use GCC 4.1.0...

                    </Offtopic>


                    Comment

                    • Christian Meier

                      #11
                      Re: extern const variable in case label

                      IIRC, just
                      const int iValue = 5;
                      no 'static', no 'extern'
                      IIRC, constants in the file scope have internal linkage (in C++).


                      Comment

                      • James Kanze

                        #12
                        Re: extern const variable in case label

                        On Oct 3, 7:49 am, "Christian Meier" <chris@no_spam. comwrote:
                        "James Kanze" <james.ka...@gm ail.comwrote:
                        With my compiler and linker I have these symbols over 10
                        000 times in my executable and I was able to reduce the
                        program size a bit with changing these constants to extern
                        which are not used in case labels.
                        That is strange. I've yet to see a compiler where they'd
                        take any space at all, as long as their address wasn't
                        taken.
                        Eventually my assumption was wrong about the more than 10 000
                        symbols for this variable.... And I have not checked whether
                        the address is taken.
                        <Offtopic: UNIX Commands and Compiler version>
                        But the command "nm MyExecutable | grep iValue | wc -l" has
                        the output "11059" at this moment.
                        We use GCC 4.1.0...
                        </Offtopic>
                        Interesting. I would have thought 0 occurances (or at most,
                        only for those where the address was being taken). It's
                        possible that in debug mode, g++ would generate them, since you
                        could presumable modify the value with a debugger, but a quick
                        check with a single module on my system (g++ 4.1.0 under Solaris
                        and Linux) didn't reveal them. Even in debug mode: "nm a.out |
                        grep staticConst" (where the actual variable was named
                        staticConst) didn't have any output. Sun CC did generate the
                        object in debug mode (as a global, no less, but with a funny
                        prefix added to the name, presumably to make it distinct), but
                        not when optimizing was turned on.

                        I'm curious. If you compile the following program:

                        static int const staticConst = 42 ;

                        int
                        main()
                        {
                        return staticConst ;
                        }

                        then do "nm a.out | grep staticConst", what do you get (with and
                        without optimizing)?

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        • James Kanze

                          #13
                          Re: extern const variable in case label

                          On Oct 3, 4:56 am, Barry <dhb2...@gmail. comwrote:

                          [...]
                          const int iValue = 5;
                          no 'static', no 'extern'
                          Both:
                          int const iValue = 5 ;
                          and
                          static int const iValue = 5 ;
                          mean exactly the same thing to the compiler. The choice of
                          which one to use is largely an issue of style; some people
                          prefer making the internal linkage explicit.

                          This is also one point where C and C++ are not compatible. If
                          the code is to be used in a header used in both languages, then
                          the static is necessary.

                          --
                          James Kanze (GABI Software) email:james.kan ze@gmail.com
                          Conseils en informatique orientée objet/
                          Beratung in objektorientier ter Datenverarbeitu ng
                          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                          Comment

                          • Christian Meier

                            #14
                            Re: extern const variable in case label

                            "James Kanze" <james.kanze@gm ail.comwrote:
                            On Oct 3, 7:49 am, "Christian Meier" <chris@no_spam. comwrote:
                            "James Kanze" <james.ka...@gm ail.comwrote:
                            With my compiler and linker I have these symbols over 10
                            000 times in my executable and I was able to reduce the
                            program size a bit with changing these constants to extern
                            which are not used in case labels.
                            That is strange. I've yet to see a compiler where they'd
                            take any space at all, as long as their address wasn't
                            taken.
                            >
                            Eventually my assumption was wrong about the more than 10 000
                            symbols for this variable.... And I have not checked whether
                            the address is taken.
                            >
                            <Offtopic: UNIX Commands and Compiler version>
                            >
                            But the command "nm MyExecutable | grep iValue | wc -l" has
                            the output "11059" at this moment.
                            We use GCC 4.1.0...
                            >
                            </Offtopic>
                            >
                            Interesting. I would have thought 0 occurances (or at most,
                            only for those where the address was being taken).
                            I don't know in which cases the address is needed. I suppose there are many
                            other situations than "&iValue".
                            What about passing it to a function which takes a "const int&" as parameter?
                            If references are implemented as pointers than the address is needed for
                            this.
                            Using this variable in such a way is not unusual in our project. Could this
                            be the reason for all (or at least almost) the symbols in my executable?

                            It's possible that in debug mode, g++ would generate them, since you
                            could presumable modify the value with a debugger, but a quick
                            check with a single module on my system (g++ 4.1.0 under Solaris
                            and Linux) didn't reveal them. Even in debug mode: "nm a.out |
                            grep staticConst" (where the actual variable was named
                            staticConst) didn't have any output. Sun CC did generate the
                            object in debug mode (as a global, no less, but with a funny
                            prefix added to the name, presumably to make it distinct), but
                            not when optimizing was turned on.
                            >
                            I'm curious. If you compile the following program:
                            >
                            static int const staticConst = 42 ;
                            >
                            int
                            main()
                            {
                            return staticConst ;
                            }
                            >
                            then do "nm a.out | grep staticConst", what do you get (with and
                            without optimizing)?
                            I don't get any output for this.

                            But for an extended version of your code, I got an indication:

                            $ cat main.cpp
                            #include <iostream>

                            static int const staticConst = 42;

                            void func(const int& ri)
                            {
                            std::cout << ri << '\n';
                            }

                            int main()
                            {
                            func(staticCons t);
                            return staticConst ;
                            }
                            $ g++ -o main main.cpp
                            $ nm main | grep staticConst
                            000000000040093 8 r staticConst
                            $ g++ -O3 -o main main.cpp
                            $ nm main | grep staticConst
                            $

                            Compiling this code without an explicit optimization level results in having
                            1 symbol staticConst. However, we are compiling everything with -O3.


                            Comment

                            • Joe Greer

                              #15
                              Re: extern const variable in case label

                              "Christian Meier" <chris@no_spam. comwrote in
                              news:bb41a$48e6 030d$3e024b42$5 661@news.hispee d.ch:
                              >
                              But for an extended version of your code, I got an indication:
                              >
                              $ cat main.cpp
                              #include <iostream>
                              >
                              static int const staticConst = 42;
                              >
                              void func(const int& ri)
                              {
                              std::cout << ri << '\n';
                              }
                              >
                              int main()
                              {
                              func(staticCons t);
                              return staticConst ;
                              }
                              $ g++ -o main main.cpp
                              $ nm main | grep staticConst
                              000000000040093 8 r staticConst
                              $ g++ -O3 -o main main.cpp
                              $ nm main | grep staticConst
                              $
                              >
                              Compiling this code without an explicit optimization level results in
                              having 1 symbol staticConst. However, we are compiling everything with
                              -O3.
                              >
                              >
                              >
                              In its simplest form, the reference takes the address of the variable and
                              thus you get a symbol. With the optimizer turned on, it probably inlines
                              the function and you no longer need the variable, thus you don't see it
                              with -O3.

                              joe

                              Comment

                              Working...