Question on header files and their use.

A

Angus

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).
 
B

Ben Bacarisse

Angus said:
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.
 
A

Angus

Angus said:
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.

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.
 
J

James Kuyper

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.
 
A

Angus

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.

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.
 
B

Ben Bacarisse

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).
 
M

Michael Angelo Ravera

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).
 
B

Ben Bacarisse

Kenneth Brody said:
On 3/29/2011 9:20 AM, Angus wrote:
[...]
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.
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>
 
P

Peter Nilsson

Angus said:
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.
 
J

James Kuyper

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.

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.
 
B

Ben Bacarisse

BruceS said:
<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.
 
R

robertwessel2

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.
 
B

BruceS

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.
 
R

robertwessel2

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





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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top