Re: About #include statements and other related questions
On Dec 8, 5:52 am, Rolf Magnus <ramag...@t-online.de> wrote:
Vicent Giner-Bosch wrote:
(1) Which is the difference between a ".cpp" file and a ".h"
file? Why is it more frequent including ".h" files than
".cpp" ones?
It's rather the other way round. If a file is supposed to be
included, you give it a name that ends in .h (other names are
also used sometimes, like e.g. .hpp or .hxx). It's basically a
convention.
More to the point, all such endings are conventions. In
practice, compilers will usually treat .c as C code; .cpp, .cxx
or .cc as C++, and various other endings as other things. (E.g.
..f for Fortran, .a or .ada for Ada, .p for Pascal, etc. Many
compilers will also pass on any ending they don't know about to
the linker.)
With regards to include, all of the compilers I know simply use
the string in the include directive as the name of the file,
with no particular mapping, so you can use literally anything
(and I've seen quite a few variations). The usual convention is
..h for C headers and .hpp, .hxx or .hh for C++ headers, but a
lot of people seem to like confusing the two. And not a few
places will introduce special endings for special types of
headers: .tcc for template implementation code (to separate it
from the header), .inl for inline function definitions, etc. (I
also use .lhh for local headers, which won't be exported, but I
think that's a personal convention. I've also used .ihh for
inline function definitions---so *.hh matches exported C++
headers, and *.*hh matches all C++ headers.)
(2) Which is the difference between #include <something>, #include
<something.h>, #include "something.h"? Are they interchangeable?
Include with <> and "" use different search paths to find the
header file. When including a system header or library
header, use <>. When including a header from your own project,
use "".
There is one difference required by the standard: where the
compiler looks for <...> must be a subset of where it looks for
"...". Typically, the compiler will look for "..." in the
directory where the file doing the include is found, then treat
it as <...>. (Formally, the standard doesn't require <...> to
even be a file, but in practice, I've only heard of one compiler
where this was the case.)
There is not really a difference between #include <something>
and #include <something.h> except that the first includes a
header named something, the other includes one named
something.h. But since they include different headers, they
are not interchangeable.
(3) I have ".cpp" example files that contain #include
<something.h> and I have to change it by #include "something.h"
in order to make it work -- I mean, if I try to compile the ".cpp"
file, I get an error when I have #include <something.h> ("No such
file or directory"), and I don't get any error or warning when I
change it by #include "something.h". It always happens the same,
with every project (even with examples, as I said), no matter which
files I am including. Is that an expected behavior?? Is it maybe
something related with MS Visual C++ options or settings??
There are compiler options that can be used to add directories
to the header search path. If you add the current directory
(".") then you can probably also use <> to include your own
headers, but the preferred way is to use "" for those.
(4) The biggest problem/question here:
I am working with the GNU Scientific Library (GSL),
specifically with GSL 1.11 "prepared" for Windows by David
Geldreich (http://david.geldreich.free.fr/dev.html). I
downloaded and unzipped the "binaries for Windows" package.
I copied the "gsl" folder (the one which is in the "include"
folder, and that contains lots of ".h" files) in the same
directory where my main ".cpp" file is.
Is there no way to correctly "install" it?
In my main ".cpp" file I have #include "gsl/gsl_cdf.h",
because #include <gsl/gsl_cdf.h> didn't work for me, as I
said at (3).
The best option would be to put all the stuff that belongs to
the library into a subdirectory of your project, then add its
header directory to the compiler's search path.
Actually, I'd make the library a separate project, and import
it. (Not sure how to do that under Visual Studios, but from the
command line, you can import something by specifying the include
path for the headers -- -I or /I -- and the filename with the
library.)
I compile the main file (Ctrl+F7), and everything is OK.
Then, I try to build the main file (F7), called
"OPCA_01.cpp", and I get this error:
""" Linking...
OPCA_01.obj : error LNK2001: unresolved external symbol
_gsl_cdf_ugaussian_P
Debug/OPCA_01.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe. """
In my program, I call a function called
"gsl_cdf_ugaussian_P", which is defined in the file
"gsl_cdf.h", which is in the "gsl" folder.
My guess is that it's not defined in that file, but rather
only declared.
And of course, that he hasn't specified the library when
linking. Or that the headers are pure C (without a conditional
``extern "C"''), and he included them as is, without wrapping
them in an ``extern "C"'' declaration. So the compiler
processed the function declarations as if they were C++, but
when it compiled the function definition in the .c file, it
processed it as C.
I don't understand why I get that estrange error. I didn't
typewrite "_gsl_cdf_ugaussian_P" in any moment.
It's a "mangled" name - a name that the compiler uses
internally to refer to that function.
Or is it? I would expect the mangled name to be more
complicated than that, with at least some sequences that aren't
legal in user C++ (like "__" or an initial "_X", where X is any
capital letter).
So, can you help me to understand what am I doing wrong???
You probably need to link to the library. The header file only
tells the compiler which functions there are and how you have
to call them (argument list, return value, ...), but it
doesn't contain the actual function code. That code is put in
a library which you have to link your program to.
Was the library delivered precompiled, or does he have to
compile it as well?
--
James Kanze