Re: What is the standard's scope for #define?
On Jun 16, 5:03 pm, Pep <pepaltavi...@yahoo.co.uk> wrote:
So my problem is one of understanding the validity of #define
pre- processor defines across source files. I thought that if
you #define in a cpp implementation file, it will be honored
in the #include interface file. This has always worked like
this for years. Now I come to build code on windows and find
that my knowledge is wrong :O
No it's not. Macro expansion and defines are handled by the
preprocessor, and ignore scope.
So a sample snippet to illustrate my question involves these 2 files
=========================
====================== interfac=
e.h
#ifndef __IMPLEMENTATION__
#define __IMPLEMENTATION__
Names with two adjacent underscores are undefined behavior.
Names starting with an underscore are in the implementation
namespace. Don't use either.
For an include guard, you'll also want to munge in some sort of
a random sequence, to avoid conflicts. (Your editor should do
this for you, when you open a new header file.)
#ifndef DEFINE_VARS
extern const char externalString[];
#else
const char externalString[] = "an extern std::string";
#endif
Note that if DEFINE_VARS is defined, externalString will have
internal linkage, and will not be visible in any other
translation unit. What you probably want is:
extern char const externalString[] = "and external string" ;
(Not that I think this technique is a good idea. If the actual
string is to be visible in a header, you might as well just use:
char const externalString[] = "..." ;
everywhere.)
=========================
====================== other.cc
#include "interface.h"
... some code ...
=========================
====================== implemen=
tation.cc
#define DEFINE_VARS
#include "interface.h"
int main(int argc, char** argv)
{
return;
Not relevant to your problem, but the above line shouldn't
compile. Since main returns an int, any return statement in
main must have a return code.
}
=========================
======================
Now based on the fact that I have #define DEFINE_VARS in
implementation.cc, I would expect interface.h to provide the
extern definitions and the declarations other.cc.
Except that you don't have an extern definitions in interface.h.
This works with g++ but not with Microsoft's compiler. With
the MS compiler I need to add /D DEFINE_VARS to the compile
command line parameters for this to work.
I get the same behavior with both. If I don't use
externalString in other.cc, no problem. If I do, the code
compiles, but fails to link. Which is the expected behavior.
BTW: when you do get an error, it would help if you cite it in
your posting. Similarly, you should cut and paste that actual
code you tried to compile -- the missing #endif in interface.hh
could be a cut and paste error (one line too few), but the
return statement in main won't compile either.
I stumbled upon a reference for c++ that clearly states that
the MS version is correct, which surprises me.
MS is correct, at least Visual Studios 8, but since it was also
correct in this regard in version 1.0 of its C compiler, I don't
think it's recent bug fix. On the other hand, MS behaves
exactly like g++, not like you describe it.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34