Question on header files and their use.

Discussion in 'C Programming' started by Angus, Mar 29, 2011.

  1. Angus

    Angus Guest

    My understanding is that #including a header file is a convenience -
    to tell the compiler that this file contains a list of some functions
    used in this source file. Is that correct?

    So eg to copy a file I can do this:

    #include <string.h>

    int main(){
    char dest[512] = {0};
    char* src = "Hello world";
    strcpy(dest, src);

    return 0;
    }

    But on that reckoning I should also be able to do this:
    char* strcpy(char *, const char *);

    int main(){
    char dest[512] = {0};
    char* src = "Hello world";
    strcpy(dest, src);

    return 0;
    }


    ie with no #include. On my compiler this compiles but it does not
    link. It is as if somehow the #include of the <string.h> file somehow
    is passing this information to the linker? Is that possible?

    If so is this compiler specific or a standard linker feature?

    So I need a parameter to pass to the linker to pass the library which
    contains strcpy? (if I do this without #including header).
    Angus, Mar 29, 2011
    #1
    1. Advertising

  2. Angus <> writes:

    > My understanding is that #including a header file is a convenience -
    > to tell the compiler that this file contains a list of some functions
    > used in this source file. Is that correct?


    If you change "convenience" to "great convenience" and "some functions"
    to "functions, types and macros" then that's about it, yes.

    > So eg to copy a file I can do this:
    >
    > #include <string.h>
    >
    > int main(){
    > char dest[512] = {0};
    > char* src = "Hello world";
    > strcpy(dest, src);
    >
    > return 0;
    > }
    >
    > But on that reckoning I should also be able to do this:
    > char* strcpy(char *, const char *);


    How do you know that's the right prototype? The pointers will be
    restrict-qualifies if you are using C99.

    > int main(){
    > char dest[512] = {0};
    > char* src = "Hello world";
    > strcpy(dest, src);
    >
    > return 0;
    > }
    >
    > ie with no #include. On my compiler this compiles but it does not
    > link. It is as if somehow the #include of the <string.h> file somehow
    > is passing this information to the linker? Is that possible?


    This is a complex question, and would be helped by some indication of
    what compiler this is and what when wrong with the link.

    <string.h> need not be a file and "including" it can have all sorts of
    effects other than just declaring things. It might, for example,
    trigger linking against the right library. These things are not
    specified by the C language so they are up for grabs.

    What is specified is that a user-supplied declaration is permitted:

    "Provided that a library function can be declared without reference to
    any type defined in a header, it is also permissible to declare the
    function and use it without including its associated header."
    7.1.4 p2

    but that does not mean there won't be extra hoops to go through to get
    the program to link.

    However, two points stand out.

    (1) Why would you want to give yourself all this extra trouble?
    (2) An answer in the specific case needs information that you've not
    provided.

    > If so is this compiler specific or a standard linker feature?
    >
    > So I need a parameter to pass to the linker to pass the library which
    > contains strcpy? (if I do this without #including header).


    Only your compiler/linker manual can say.

    --
    Ben.
    Ben Bacarisse, Mar 29, 2011
    #2
    1. Advertising

  3. Angus

    Angus Guest

    On Mar 29, 2:06 pm, Ben Bacarisse <> wrote:
    > Angus <> writes:
    > > My understanding is that #including a header file is a convenience -
    > > to tell the compiler that this file contains a list of some functions
    > > used in this source file.  Is that correct?

    >
    > If you change "convenience" to "great convenience" and "some functions"
    > to "functions, types and macros" then that's about it, yes.
    >
    > > So eg to copy a file I can do this:

    >
    > > #include <string.h>

    >
    > > int main(){
    > >    char dest[512] = {0};
    > >    char* src = "Hello world";
    > >    strcpy(dest, src);

    >
    > >    return 0;
    > > }

    >
    > > But on that reckoning I should also be able to do this:
    > > char*  strcpy(char *, const char *);

    >
    > How do you know that's the right prototype?  The pointers will be
    > restrict-qualifies if you are using C99.
    >
    > > int main(){
    > >    char dest[512] = {0};
    > >    char* src = "Hello world";
    > >    strcpy(dest, src);

    >
    > >    return 0;
    > > }

    >
    > > ie with no #include.  On my compiler this compiles but it does not
    > > link.  It is as if somehow the #include of the <string.h> file somehow
    > > is passing this information to the linker?  Is that possible?

    >
    > This is a complex question, and would be helped by some indication of
    > what compiler this is and what when wrong with the link.
    >
    > <string.h> need not be a file and "including" it can have all sorts of
    > effects other than just declaring things.  It might, for example,
    > trigger linking against the right library.  These things are not
    > specified by the C language so they are up for grabs.
    >
    > What is specified is that a user-supplied declaration is permitted:
    >
    >   "Provided that a library function can be declared without reference to
    >   any type defined in a header, it is also permissible to declare the
    >   function and use it without including its associated header."
    >                                                                7.1.4 p2
    >
    > but that does not mean there won't be extra hoops to go through to get
    > the program to link.
    >
    > However, two points stand out.
    >
    > (1) Why would you want to give yourself all this extra trouble?
    > (2) An answer in the specific case needs information that you've not
    > provided.
    >
    > > If so is this compiler specific or a standard linker feature?

    >
    > > So I need a parameter to pass to the linker to pass the library which
    > > contains strcpy? (if I do this without #including header).

    >
    > Only your compiler/linker manual can say.
    >
    > --
    > Ben.


    Thanks for your answer. No this is not something I would want to do,
    rather a way to learn how linking etc works.

    My compiler is MS VC++ version 6. I guess I need to study the
    compiler docs to get a link working without the #include.
    Angus, Mar 29, 2011
    #3
  4. Angus

    James Kuyper Guest

    On 03/29/2011 08:16 AM, Angus wrote:
    > My understanding is that #including a header file is a convenience -
    > to tell the compiler that this file contains a list of some functions
    > used in this source file. Is that correct?


    Ideally, everything of importance should be defined/declared only once;
    when you keep multiple copies of something, you open up the possibility
    of mistakenly changing it in one place, but not in other places. Header
    files allow you to use the same definitions/declarations in many
    different translation units, even though there's only one header file
    containing the actual text of those definitions/declarations.

    The standard headers serve a similar purpose for the standard library
    functions.

    > So eg to copy a file I can do this:
    >
    > #include<string.h>
    >
    > int main(){
    > char dest[512] = {0};
    > char* src = "Hello world";
    > strcpy(dest, src);
    >
    > return 0;
    > }
    >
    > But on that reckoning I should also be able to do this:
    > char* strcpy(char *, const char *);


    It is permitted for you to do this, so long as you don't rely upon types
    defined in one of the headers (such as size_t), but you're not
    guaranteed good results unless your declaration is compatible with the
    correct one. Taking advantage of this permission is a bad idea. There's
    no good reason for not using the #include, just a lot of bad reasons.

    > int main(){
    > char dest[512] = {0};
    > char* src = "Hello world";
    > strcpy(dest, src);
    >
    > return 0;
    > }
    >
    >
    > ie with no #include. On my compiler this compiles but it does not
    > link. It is as if somehow the #include of the<string.h> file somehow
    > is passing this information to the linker? Is that possible?


    It seems unlikely, but it's certainly possible. If you invoke the linker
    by hand, you may have to inform it to look for the C standard library,
    and you might have to tell it where to look for that library. As a
    general rule, if using a compiler that can run the linker for you, it's
    best to make use of that capability - the compiler should know where to
    look for these things.

    > If so is this compiler specific or a standard linker feature?


    I'm leaning in favor of this being a user mistake, rather than any
    problem with the compiler or linker. Please provide the exact list of
    commands you issued, and the complete text of any error messages
    produced. Don't leave anything out. Don't trust your own judgment as to
    what is important and what is meaningless.
    --
    James Kuyper
    James Kuyper, Mar 29, 2011
    #4
  5. Angus

    Angus Guest

    On Mar 29, 2:32 pm, James Kuyper <> wrote:
    > On 03/29/2011 08:16 AM, Angus wrote:
    >
    > > My understanding is that #including a header file is a convenience -
    > > to tell the compiler that this file contains a list of some functions
    > > used in this source file.  Is that correct?

    >
    > Ideally, everything of importance should be defined/declared only once;
    > when you keep multiple copies of something, you open up the possibility
    > of mistakenly changing it in one place, but not in other places. Header
    > files allow you to use the same definitions/declarations in many
    > different translation units, even though there's only one header file
    > containing the actual text of those definitions/declarations.
    >
    > The standard headers serve a similar purpose for the standard library
    > functions.
    >
    > > So eg to copy a file I can do this:

    >
    > > #include<string.h>

    >
    > > int main(){
    > >     char dest[512] = {0};
    > >     char* src = "Hello world";
    > >     strcpy(dest, src);

    >
    > >     return 0;
    > > }

    >
    > > But on that reckoning I should also be able to do this:
    > > char*  strcpy(char *, const char *);

    >
    > It is permitted for you to do this, so long as you don't rely upon types
    > defined in one of the headers (such as size_t), but you're not
    > guaranteed good results unless your declaration is compatible with the
    > correct one. Taking advantage of this permission is a bad idea. There's
    > no good reason for not using the #include, just a lot of bad reasons.
    >
    > > int main(){
    > >     char dest[512] = {0};
    > >     char* src = "Hello world";
    > >     strcpy(dest, src);

    >
    > >     return 0;
    > > }

    >
    > > ie with no #include.  On my compiler this compiles but it does not
    > > link.  It is as if somehow the #include of the<string.h>  file somehow
    > > is passing this information to the linker?  Is that possible?

    >
    > It seems unlikely, but it's certainly possible. If you invoke the linker
    > by hand, you may have to inform it to look for the C standard library,
    > and you might have to tell it where to look for that library. As a
    > general rule, if using a compiler that can run the linker for you, it's
    > best to make use of that capability - the compiler should know where to
    > look for these things.
    >
    > > If so is this compiler specific or a standard linker feature?

    >
    > I'm leaning in favor of this being a user mistake, rather than any
    > problem with the compiler or linker. Please provide the exact list of
    > commands you issued, and the complete text of any error messages
    > produced. Don't leave anything out. Don't trust your own judgment as to
    > what is important and what is meaningless.
    > --
    > James Kuyper


    The problem was that this is a C++ compiler. The string.h also
    contains:

    #ifdef __cplusplus
    extern "C" {
    #endif

    char* strcpy(char *, const char *);

    #ifdef __cplusplus

    To tell the C++ compiler that these functions, ie strcpy, uses C
    linkage rules (which are different from C++).

    So I just missed this bit. If my other function was from a library
    generated with a C++ compiler then this problem would not have been
    encountered.
    Angus, Mar 29, 2011
    #5
  6. Angus <> writes:

    <snip>>
    > Thanks for your answer. No this is not something I would want to do,
    > rather a way to learn how linking etc works.


    The best way to learn about linking is to read about it. I can give you
    a pointer...

    > My compiler is MS VC++ version 6. I guess I need to study the
    > compiler docs to get a link working without the #include.


    .... and it turns out from another post that are using C++ not C. They
    are two different (though closely related) languages. But they differ
    in exactly the case you care about. Do some reading about "name
    mangling" to get started.

    If you are in fact using C++, then you should be posting in
    comp.lang.c++. If you want to write C, you will be much better of
    feeding it to a C compiler (and from what I hear, MS VC++ makes a fine C
    compiler if you use the right incantations).

    --
    Ben.
    Ben Bacarisse, Mar 29, 2011
    #6
  7. On Mar 29, 5:16 am, Angus <> wrote:
    > My understanding is that #including a header file is a convenience -
    > to tell the compiler that this file contains a list of some functions
    > used in this source file.  Is that correct?
    >
    > So eg to copy a file I can do this:
    >
    > #include <string.h>
    >
    > int main(){
    >    char dest[512] = {0};
    >    char* src = "Hello world";
    >    strcpy(dest, src);
    >
    >    return 0;
    >
    > }
    >
    > But on that reckoning I should also be able to do this:
    > char*  strcpy(char *, const char *);
    >
    > int main(){
    >    char dest[512] = {0};
    >    char* src = "Hello world";
    >    strcpy(dest, src);
    >
    >    return 0;
    >
    > }
    >
    > ie with no #include.  On my compiler this compiles but it does not
    > link.  It is as if somehow the #include of the <string.h> file somehow
    > is passing this information to the linker?  Is that possible?
    >
    > If so is this compiler specific or a standard linker feature?
    >
    > So I need a parameter to pass to the linker to pass the library which
    > contains strcpy? (if I do this without #including header).


    Others have given you truthful and useful information about
    #include'ing header files.

    The #include mechanism allows you to include ANY C code (or compiler
    specific code) that you like. Yes, it is most often used for function
    prototypes, type definitions, and macros, but there is nothing that
    prevents you from using it to declare a group of local variables that
    you want to make sure that you declare the same way every time or even
    to make certain that the guts of three functions do everything exactly
    the same way in the middle after some different declarations and
    initialization and possibly in some pre-exit handling. This would be a
    reasonable way, for instance, of creating some parallel functions that
    differ only in the types of the arguments. (C++ has template functions
    for this).
    Michael Angelo Ravera, Mar 29, 2011
    #7
  8. Kenneth Brody <> writes:

    > On 3/29/2011 9:20 AM, Angus wrote:

    <snip>
    > [...]
    >> Thanks for your answer. No this is not something I would want to do,
    >> rather a way to learn how linking etc works.

    >
    > But this has nothing to do with linking, and everything to do with
    > compiling.


    It's hard to draw the line between the two but since we now know what
    was wrong it seems unfair to say it had nothing to do with linking.

    >> My compiler is MS VC++ version 6. I guess I need to study the
    >> compiler docs to get a link working without the #include.

    >
    > Why? What are you hoping to accomplish by avoiding #include? It's
    > one thing to look into system-supplied headers to get a feel for how
    > things are implemented, and perhaps learn a few things. But, to use
    > them to pull out parts of them and include them in your program, so
    > you can avoid the #include (as it appears to be the case here), is
    > something different entirely.
    >
    > If it doesn't link when you leave off the #include, it's because it
    > didn't compile properly. Even if it compiled "clean", it doesn't mean
    > it compiled "properly". Consider the case where you call a function,
    > which in reality is a macro defined in the non-included header. It
    > could compile "clean", yet the linker will be unable to find the
    > function, since it doesn't really exist.


    Not for a standard function in a standard header. You are specifically
    permitted to provide the declaration yourself; and any function
    implemented by a macro must also be available as a real function. I.e.

    #include <string.h>
    /* ... */
    (strcpy)(dst, src);

    must work.

    By the way, I agree wholeheartedly that omitting standard headers is not
    a good idea -- I just think want to get the technical details straight.

    <snip>
    --
    Ben.
    Ben Bacarisse, Mar 29, 2011
    #8
  9. Angus <> wrote:
    > The problem was that this is a C++ compiler.  


    So you have a C++ question, not a C one.

    > The string.h also
    > contains:
    >
    > #ifdef  __cplusplus
    > extern "C" {
    > #endif
    >
    > char*  strcpy(char *, const char *);
    >
    > #ifdef  __cplusplus
    >
    > To tell the C++ compiler that these functions, ie strcpy,
    > uses C linkage rules (which are different from C++).


    In C++, it's actually implementation defined whether the C library
    functions have C or C++ linkage. In other words, you pretty much
    have to include the headers to C library functions if you're
    compiling under C++.

    > So I just missed this bit.


    Beware other subtle language inconsistencies that won't be picked
    up so easily. Don't use a C++ compiler to compile C unless you
    know both languages extremely well.

    --
    Peter
    Peter Nilsson, Mar 30, 2011
    #9
  10. Angus

    James Kuyper Guest

    On 03/29/2011 09:54 AM, Angus wrote:
    > On Mar 29, 2:32�pm, James Kuyper<> wrote:
    >> On 03/29/2011 08:16 AM, Angus wrote:

    ....
    >>> int main(){
    >>> � � char dest[512] = {0};
    >>> � � char* src = "Hello world";
    >>> � � strcpy(dest, src);

    >>
    >>> � � return 0;
    >>> }

    >>
    >>> ie with no #include. �On my compiler this compiles but it does not
    >>> link. �It is as if somehow the #include of the<string.h> �file somehow
    >>> is passing this information to the linker? �Is that possible?

    ....
    >> I'm leaning in favor of this being a user mistake, rather than any
    >> problem with the compiler or linker. Please provide the exact list of
    >> commands you issued, and the complete text of any error messages
    >> produced. Don't leave anything out. Don't trust your own judgment as to
    >> what is important and what is meaningless.
    >> --
    >> James Kuyper

    >
    > The problem was that this is a C++ compiler. The string.h also
    > contains:
    >
    > #ifdef __cplusplus
    > extern "C" {
    > #endif
    >
    > char* strcpy(char *, const char *);
    >
    > #ifdef __cplusplus
    >
    > To tell the C++ compiler that these functions, ie strcpy, uses C
    > linkage rules (which are different from C++).


    So I was right - user error. If you were compiling this as C++ code, why
    did you ask the question in a newsgroup associated with C? The rules of
    the two languages are different, as you've just demonstrated.

    You can write C code that will compile just fine as C++ code, but in
    order to do that you should be aware of the differences between the two
    languages that apply even to code which will compile equally well in
    either languages. One of the key things needed to ensure such
    cross-language compatibility is to use the standard C headers, which are
    also available in C++. The C++ versions of the C standard headers handle
    details like this for you, so that the differences between the two
    languages are less visible.

    That is an example of why it's not a good idea to make use of the
    permissions you are given to provide your own declarations for standard
    library functions.
    --
    James Kuyper
    James Kuyper, Mar 30, 2011
    #10
  11. BruceS <> writes:

    > On Mar 29, 7:06 am, Ben Bacarisse <> wrote:
    > <snip>
    >> <string.h> need not be a file and "including" it can have all sorts of
    >> effects other than just declaring things.  It might, for example,
    >> trigger linking against the right library.

    > <snip>
    >
    > How does including a header trigger linking to a specific library?


    Why could it not? I'm not talking about something that does happen,
    just something that might. It would be very useful behaviour in an IDE
    (particularly for non-standard headers).

    > Are you talking about some name-replacement macro making what looks
    > like a call to foo() actually a call to bar(), or something else
    > entirely? Maybe it's just too early in the morning, but this sounds
    > like something I'm not aware of, and I always appreciate learning new
    > things about C.


    I doubt it happens. The point I was making was that without any
    information from the OP, we are left to speculate about what might be
    going on including things that I can only image in hypothetical
    environments.

    --
    Ben.
    Ben Bacarisse, Mar 30, 2011
    #11
  12. Angus

    Guest

    On Mar 30, 11:26 am, Ben Bacarisse <> wrote:
    > BruceS <> writes:
    > > On Mar 29, 7:06 am, Ben Bacarisse <> wrote:
    > > <snip>
    > >> <string.h> need not be a file and "including" it can have all sorts of
    > >> effects other than just declaring things.  It might, for example,
    > >> trigger linking against the right library.

    > > <snip>

    >
    > > How does including a header trigger linking to a specific library?

    >
    > Why could it not?  I'm not talking about something that does happen,
    > just something that might.  It would be very useful behaviour in an IDE
    > (particularly for non-standard headers).



    For at least one example where you can do just that, MS VC allows you
    to specify:

    #pragma comment(lib, "libraryname")

    Which adds libraryname.lib to the list of libraries to be searched by
    the linker.

    I don't think GCC has an equivalent.
    , Mar 30, 2011
    #12
  13. Angus

    BruceS Guest

    On Mar 30, 11:51 am, ""
    <> wrote:
    > On Mar 30, 11:26 am, Ben Bacarisse <> wrote:
    >
    > > BruceS <> writes:
    > > > On Mar 29, 7:06 am, Ben Bacarisse <> wrote:
    > > > <snip>
    > > >> <string.h> need not be a file and "including" it can have all sorts of
    > > >> effects other than just declaring things.  It might, for example,
    > > >> trigger linking against the right library.
    > > > <snip>

    >
    > > > How does including a header trigger linking to a specific library?

    >
    > > Why could it not?  I'm not talking about something that does happen,
    > > just something that might.  It would be very useful behaviour in an IDE
    > > (particularly for non-standard headers).


    OK. Thanks, Ben. I thought you had something specific in mind, and
    was looking forward to learning a new wrinkle.

    > For at least one example where you can do just that, MS VC allows you
    > to specify:
    >
    >    #pragma comment(lib, "libraryname")
    >
    > Which adds libraryname.lib to the list of libraries to be searched by
    > the linker.
    >
    > I don't think GCC has an equivalent.


    This is more what I was wondering about. So if you just compile, the
    pragma has done something with the .o that leads the linker to later
    include libraryname in the list? That's actually pretty cool. I
    generally use VC just for C# and C++, not C. I'll have to try that
    out, if I can think of a situation where I'd want to specify a library
    in source. Thanks Robert.
    BruceS, Mar 31, 2011
    #13
  14. Angus

    Guest

    On Mar 30, 9:02 pm, BruceS <> wrote:
    > On Mar 30, 11:51 am, ""
    >
    >
    >
    >
    >
    > <> wrote:
    > > On Mar 30, 11:26 am, Ben Bacarisse <> wrote:

    >
    > > > BruceS <> writes:
    > > > > On Mar 29, 7:06 am, Ben Bacarisse <> wrote:
    > > > > <snip>
    > > > >> <string.h> need not be a file and "including" it can have all sorts of
    > > > >> effects other than just declaring things.  It might, for example,
    > > > >> trigger linking against the right library.
    > > > > <snip>

    >
    > > > > How does including a header trigger linking to a specific library?

    >
    > > > Why could it not?  I'm not talking about something that does happen,
    > > > just something that might.  It would be very useful behaviour in anIDE
    > > > (particularly for non-standard headers).

    >
    > OK.  Thanks, Ben.  I thought you had something specific in mind, and
    > was looking forward to learning a new wrinkle.
    >
    > > For at least one example where you can do just that, MS VC allows you
    > > to specify:

    >
    > >    #pragma comment(lib, "libraryname")

    >
    > > Which adds libraryname.lib to the list of libraries to be searched by
    > > the linker.

    >
    > > I don't think GCC has an equivalent.

    >
    > This is more what I was wondering about.  So if you just compile, the
    > pragma has done something with the .o that leads the linker to later
    > include libraryname in the list?  That's actually pretty cool.  I
    > generally use VC just for C# and C++, not C.  I'll have to try that
    > out, if I can think of a situation where I'd want to specify a library
    > in source.



    In MS's case, this used to be done with a COMENT record in the OMF*
    file, with a particular subtype (0x9f**, if anyone cares) specifying
    that the string contains a library name. This is where the #pragma
    got its name.

    These days, MSVC writes a .drectve section into the PE/COFF object
    file, which contains a linker command line parameter string (which the
    linker parses along with the "real" command line. So if you'd put the
    above #pragma in some code, you'd find '/DEFAULTLIB:"libraryname" '
    in a string referenced from the .drectve section.

    This works in (unmanaged) C++, too, of course, and there are
    provisions for the same sort of data in a .NET assembly, but I've
    never cared about the internals of MSIL object files enough to figure
    out the details.


    *The old, Intel defined, object module format that MS used before
    switching to PE/COFF for Win32

    **I’m not sure if that’s an Intel defined subtype, or an MS extension
    , Mar 31, 2011
    #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. Steven Cheng[MSFT]

    RE: Resource files and their advantage

    Steven Cheng[MSFT], Apr 15, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    730
    Steven Cheng[MSFT]
    Apr 15, 2005
  2. Chris Mantoulidis
    Replies:
    3
    Views:
    406
    Jared Dykstra
    Dec 20, 2003
  3. John Smith

    Header files included in header files

    John Smith, Jul 21, 2004, in forum: C Programming
    Replies:
    18
    Views:
    596
    Jack Klein
    Jul 24, 2004
  4. Replies:
    3
    Views:
    1,277
    Walter Roberson
    May 1, 2006
  5. mlt
    Replies:
    2
    Views:
    813
    Jean-Marc Bourguet
    Jan 31, 2009
Loading...

Share This Page