scope and linkage

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

    #1

    scope and linkage

    I'm working on a disassembler for a school project.

    Things work but I get compiler warnings as follows:
    cc -W -Wall -pedantic -ansi main.c
    defs.h:44: warning: 'blah' defined but not used

    blah is a static variable, so visible only to defs.h (and files that
    include defs.h?).
    Without the static qualifier the compiler bails with
    main.o: multiple definition of 'blah'
    main.o: first defined here
    collect2: ld returned 1 exit status
    make: *** [all] Error 1


    The warnings are invisible w/o the -Wall compile flag.
    I just want to know if there is a way to declare 'blah' that will avoid
    the warning.

    here is the program structure:

    FILE: main.c
    #include dis.h
    /* only calls one function in dis.h */

    FILE: dis.h
    #include defs.h

    FILE: dis.c
    #include dis.h
    /* uses almost everything in defs.h */

    FILE: defs.h
    static const char* blah[ SIZE ] = { ... };


    Like I said, I'm just looking to compile cleanly with the CFLAGS above.
    thanks for any help!

  • Jack Klein

    #2
    Re: scope and linkage

    On 31 Mar 2006 11:49:33 -0800, "rick" <rick.shelton@g mail.com> wrote
    in comp.lang.c:
    [color=blue]
    > I'm working on a disassembler for a school project.
    >
    > Things work but I get compiler warnings as follows:
    > cc -W -Wall -pedantic -ansi main.c
    > defs.h:44: warning: 'blah' defined but not used
    >
    > blah is a static variable, so visible only to defs.h (and files that
    > include defs.h?).[/color]

    An included file like "defs.h" has no visibility at all. Translation
    units have things with visibility in them. A translation unit is
    roughly a compiled source file plus everything it includes.
    [color=blue]
    > Without the static qualifier the compiler bails with
    > main.o: multiple definition of 'blah'
    > main.o: first defined here
    > collect2: ld returned 1 exit status
    > make: *** [all] Error 1
    >
    >
    > The warnings are invisible w/o the -Wall compile flag.
    > I just want to know if there is a way to declare 'blah' that will avoid
    > the warning.[/color]

    Your problem is bigger than the warning. The warning is telling you
    that you are creating, not just declaring, an array in main.c that is
    not referenced by any code in main.c. It's address is not even taken,
    so it is completely unused by your program. The contents of defs.h is
    a declaration, but is it also a definition that creates and
    initializes blah.
    [color=blue]
    > here is the program structure:
    >
    > FILE: main.c
    > #include dis.h
    > /* only calls one function in dis.h */
    >
    > FILE: dis.h
    > #include defs.h
    >
    > FILE: dis.c
    > #include dis.h
    > /* uses almost everything in defs.h */
    >
    > FILE: defs.h
    > static const char* blah[ SIZE ] = { ... };
    >
    >
    > Like I said, I'm just looking to compile cleanly with the CFLAGS above.
    > thanks for any help![/color]

    The problem is that you are defining data in a header, which is
    incorrect. Your program ends up with two identical copies of the blah
    array, perhaps even more than two if any other source files include
    defs.h directly or indirectly. If you have a hundred C source files
    in your program, and each of them includes defs.h directly or
    indirectly, you will end up with one hundred identical copies of this
    array.

    The solution is simple, don't define data objects in an include file.
    If only dis.c needs to access this data, put it in dis.c.

    If more than one source file needs to access it, instead of putting it
    in a header that causes each source file to create its own copy, do
    this instead.

    Create a header file called blah.h, it should contain:

    extern const char * const blah [SIZE];

    ....assuming that you never modify the pointers in the array.

    Include this in all source files that need to reference these strings.
    Then in exactly one source file, or in a new source file named blah.c,
    put:

    const char * const blah [SIZE] = { /* initializers */ };

    Remember, defining data objects in include files is almost always a
    bad idea.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
    alt.comp.lang.l earn.c-c++

    Comment

    • Fred Kleinschmidt

      #3
      Re: scope and linkage


      "rick" <rick.shelton@g mail.com> wrote in message
      news:1143834573 .878988.211490@ z34g2000cwc.goo glegroups.com.. .[color=blue]
      > I'm working on a disassembler for a school project.
      >
      > Things work but I get compiler warnings as follows:
      > cc -W -Wall -pedantic -ansi main.c
      > defs.h:44: warning: 'blah' defined but not used
      >
      > blah is a static variable, so visible only to defs.h (and files that
      > include defs.h?).
      > Without the static qualifier the compiler bails with
      > main.o: multiple definition of 'blah'
      > main.o: first defined here
      > collect2: ld returned 1 exit status
      > make: *** [all] Error 1
      >
      >
      > The warnings are invisible w/o the -Wall compile flag.
      > I just want to know if there is a way to declare 'blah' that will avoid
      > the warning.
      >
      > here is the program structure:
      >
      > FILE: main.c
      > #include dis.h
      > /* only calls one function in dis.h */
      >
      > FILE: dis.h
      > #include defs.h
      >
      > FILE: dis.c
      > #include dis.h
      > /* uses almost everything in defs.h */
      >
      > FILE: defs.h
      > static const char* blah[ SIZE ] = { ... };
      >
      >
      > Like I said, I'm just looking to compile cleanly with the CFLAGS above.
      > thanks for any help!
      >[/color]

      the compiler is telling you that you have defined a variable called blah,
      but that variable is never referenced in your program. To compile "cleanly",
      you have two choices:
      1) remove the definition of blah from defs.h,
      or
      2) Use blah somewhere in your program
      --
      Fred L. Kleinschmidt
      Boeing Associate Technical Fellow
      Technical Architect, Software Reuse Project


      Comment

      • rick

        #4
        Re: scope and linkage

        Well that explains a lot!

        Using the blah.h and blah.c idea,
        the program now builds without incident.

        Finally a good explanation of scope across multiple files!
        Thanks!

        Comment

        • Jack Klein

          #5
          Re: scope and linkage

          On 31 Mar 2006 11:49:33 -0800, "rick" <rick.shelton@g mail.com>
          wrote
          in comp.lang.c:
          [color=blue]
          > I'm working on a disassembler for a school project.
          >
          > Things work but I get compiler warnings as follows:
          > cc -W -Wall -pedantic -ansi main.c
          > defs.h:44: warning: 'blah' defined but not used
          >
          > blah is a static variable, so visible only to defs.h (and files that
          > include defs.h?).
          >[/color]
          An included file like "defs.h" has no visibility at all. Translation
          units have things with visibility in them. A translation unit is
          roughly a compiled source file plus everything it includes.
          [color=blue]
          > Without the static qualifier the compiler bails with
          > main.o: multiple definition of 'blah'
          > main.o: first defined here
          > collect2: ld returned 1 exit status
          > make: *** [all] Error 1
          >
          >
          > The warnings are invisible w/o the -Wall compile flag.
          > I just want to know if there is a way to declare 'blah' that will[/color]
          avoid[color=blue]
          > the warning.
          >[/color]
          Your problem is bigger than the warning. The warning is telling you
          that you are creating, not just declaring, an array in main.c that is
          not referenced by any code in main.c. It's address is not even taken,
          so it is completely unused by your program. The contents of defs.h is
          a declaration, but is it also a definition that creates and
          initializes blah.
          [color=blue]
          > here is the program structure:
          >
          > FILE: main.c
          > #include dis.h
          > /* only calls one function in dis.h */
          >
          > FILE: dis.h
          > #include defs.h
          >
          > FILE: dis.c
          > #include dis.h
          > /* uses almost everything in defs.h */
          >
          > FILE: defs.h
          > static const char* blah[ SIZE ] = { ... };
          >
          >
          > Like I said, I'm just looking to compile cleanly with the CFLAGS[/color]
          above.[color=blue]
          > thanks for any help!
          >[/color]
          The problem is that you are defining data in a header, which is
          incorrect. Your program ends up with two identical copies of the blah
          array, perhaps even more than two if any other source files include
          defs.h directly or indirectly. If you have a hundred C source files
          in your program, and each of them includes defs.h directly or
          indirectly, you will end up with one hundred identical copies of this
          array.

          The solution is simple, don't define data objects in an include file.
          If only dis.c needs to access this data, put it in dis.c.

          If more than one source file needs to access it, instead of putting it
          in a header that causes each source file to create its own copy, do
          this instead.

          Create a header file called blah.h, it should contain:

          extern const char * const blah [SIZE];

          ....assuming that you never modify the pointers in the array.

          Include this in all source files that need to reference these strings.
          Then in exactly one source file, or in a new source file named blah.c,
          put:

          const char * const blah [SIZE] = { /* initializers */ };

          Remember, defining data objects in include files is almost always a
          bad idea.

          --
          Jack Klein
          Home: http://JK-Technology.Com
          FAQs for
          comp.lang.c http://c-faq.com/
          comp.lang.c++ http://www.parashift.com/c++-faq-lite/
          alt.comp.lang.l earn.c-c++


          Comment

          • CBFalconer

            #6
            Re: scope and linkage

            rick wrote:[color=blue]
            >[/color]
            .... snip ...[color=blue]
            >
            > here is the program structure:
            >
            > FILE: main.c
            > #include dis.h
            > /* only calls one function in dis.h */
            >
            > FILE: dis.h
            > #include defs.h
            >
            > FILE: dis.c
            > #include dis.h
            > /* uses almost everything in defs.h */
            >
            > FILE: defs.h
            > static const char* blah[ SIZE ] = { ... };
            >
            > Like I said, I'm just looking to compile cleanly with the CFLAGS
            > above. thanks for any help![/color]

            Several things. First, why does dis.h include defs.h in the first
            place? The only purpose of dis.h is to expose things in dis.c that
            need to be accessed from other modules, the only one of which I see
            is main.c. So the only thing needed in dis.h is that function
            called from main.

            Second, why does defs.h define any data storage in the first
            place? That is generally a no-no. The storage is only used in
            dis.c, so simply define it within difs.c in the first place.
            Apparently this applies to everything in defs.h anyhow, so why does
            that file even exist?

            Since only one function within difs.c is ever called from outside,
            every other function in that module should be classified as
            'static'. Similarly for any data (hopefully none) that is declared
            in file scope.

            Restrict access and scope as far as possible, and you should have
            no problems.

            --
            "If you want to post a followup via groups.google.c om, don't use
            the broken "Reply" link at the bottom of the article. Click on
            "show options" at the top of the article, then click on the
            "Reply" at the bottom of the article headers." - Keith Thompson
            More details at: <http://cfaj.freeshell. org/google/>
            Also see <http://www.safalra.com/special/googlegroupsrep ly/>


            Comment

            Working...