Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Question on header files and their use.

Reply
Thread Tools

Question on header files and their use.

 
 
Angus
Guest
Posts: n/a
 
      03-29-2011
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).
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-29-2011
Angus <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
 
Angus
Guest
Posts: n/a
 
      03-29-2011
On Mar 29, 2:06*pm, Ben Bacarisse <(E-Mail Removed)> wrote:
> Angus <(E-Mail Removed)> 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.

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      03-29-2011
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
 
Reply With Quote
 
Angus
Guest
Posts: n/a
 
      03-29-2011
On Mar 29, 2:32*pm, James Kuyper <(E-Mail Removed)> 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.

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-29-2011
Angus <(E-Mail Removed)> 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.
 
Reply With Quote
 
Michael Angelo Ravera
Guest
Posts: n/a
 
      03-29-2011
On Mar 29, 5:16*am, Angus <(E-Mail Removed)> 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).
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      03-29-2011
Kenneth Brody <(E-Mail Removed)> 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.
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      03-30-2011
Angus <(E-Mail Removed)> 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
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      03-30-2011
On 03/29/2011 09:54 AM, Angus wrote:
> On Mar 29, 2:32�pm, James Kuyper<(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Header files with "header.h" or <header.h> ?? mlt C++ 2 01-31-2009 02:54 PM
UNIX header files to Windows header files anand.ba@gmail.com C Programming 3 05-01-2006 03:57 PM
Header files included in header files John Smith C Programming 18 07-24-2004 04:55 AM
What the pros use to power their flashes... and their digital cameras. Dan Sullivan Digital Photography 21 01-04-2004 04:40 PM
Seperate compilation (header files n' their implementations) Chris Mantoulidis C++ 3 12-20-2003 04:25 AM



Advertisments