Macro does not work in source code.

N

Nephi Immortal

I created macro in all header and source codes. The TEST condition
must always be true in demo.cpp, but error message displays

Main.obj : error LNK2001: unresolved external symbol "char * _MSG_" (?
_MSG_@@3PADA)
C:\My Projects\RGB\Debug\RGB.exe : fatal error LNK1120: 1 unresolved
externals

It means that main.cpp tries to link char _MSG_, but the definition in
demo.cpp is not found because the TEST condition is set to false.

Why macro does not work?


// Demo.h
#ifdef DEMO_H

#if defined( TEST )
extern char _MSG_[ 256 ];
#else
extern wchar_t _MSG_[ 256 ];
#endif

#endif // DEMO_H


// Demo.cpp
#if defined( TEST )
char _MSG_[ 256 ] = "This is char type.";
#else
wchar_t _MSG_[ 256 ] = L"This is wchar_t type."
#endif

// main.cpp

#define TEST
#include "Demo.h"


int main()
{
#ifdef TEST
char *p = _MSG_;
#else
wchar_t *p = _MSG_;
#endif
}
 
R

red floyd

I created macro in all header and source codes. The TEST condition
must always be true in demo.cpp, but error message displays

Main.obj : error LNK2001: unresolved external symbol "char * _MSG_" (?
_MSG_@@3PADA)
C:\My Projects\RGB\Debug\RGB.exe : fatal error LNK1120: 1 unresolved
externals

It means that main.cpp tries to link char _MSG_, but the definition in
demo.cpp is not found because the TEST condition is set to false.

Why macro does not work?


// Demo.h
#ifdef DEMO_H

#if defined( TEST )
extern char _MSG_[ 256 ];
#else
extern wchar_t _MSG_[ 256 ];
#endif

#endif // DEMO_H

Aside from Sam's comments, your code is ill-formed. Any identifier
beginning with an underscore followed by an uppercase letter (such
as, _MSG_) is reserved to the implementation, and may not be defined
for use by the program.
 
J

Juha Nieminen

red floyd said:
Aside from Sam's comments, your code is ill-formed. Any identifier
beginning with an underscore followed by an uppercase letter (such
as, _MSG_) is reserved to the implementation, and may not be defined
for use by the program.

I thought it's any identifier beginning with an underscore, period.
 
A

Alf P. Steinbach

I thought it's any identifier beginning with an underscore, period.

No. The three main cases are

1. Beginning with underscore followed by uppercase.
2. Two consecutive underscores anywhere in the name.
3. For the global namespace only, beginning with underscore.

However, the common use of unqualified names means that one should
better not define names that begin with underscore even in class scope.

It gives the wrong signal to a reader of the code...


Cheers & hth.,

- Alf
 
M

MJ_India

I created macro in all header and source codes.  The TEST condition
must always be true in demo.cpp, but error message displays

Main.obj : error LNK2001: unresolved external symbol "char * _MSG_" (?
_MSG_@@3PADA)
C:\My Projects\RGB\Debug\RGB.exe : fatal error LNK1120: 1 unresolved
externals

It means that main.cpp tries to link char _MSG_, but the definition in
demo.cpp is not found because the TEST condition is set to false.

Why macro does not work?

// Demo.h
#ifdef DEMO_H

#if defined( TEST )
        extern char _MSG_[ 256 ];
#else
        extern wchar_t _MSG_[ 256 ];
#endif

#endif // DEMO_H

// Demo.cpp
#if defined( TEST )
        char _MSG_[ 256 ] = "This is char type.";
#else
        wchar_t _MSG_[ 256 ] = L"This is wchar_t type."
#endif

// main.cpp

#define TEST
#include "Demo.h"

int main()
{
#ifdef TEST
        char *p = _MSG_;
#else
        wchar_t *p = _MSG_;
#endif







}

Two blunders in the code are:
1. #ifdef DEMO_H is masking all the code of file demo.h
Are you sure you don't want to write
#ifndef DEMO_H
#define DEMO_H
.....
#endif
[Prefer to use #pragma once instead of ifndef guards]
2. wchar_t _MSG_[ 256 ] = L"This is wchar_t type." , semicolon is
missing.

After fixing above 2, you should be able to compile and link but
needless to say
code is very ill formatted. Read above posted replies carefully to
understand why?

-Mohit
 
J

Jorgen Grahn

....

1. #ifdef DEMO_H is masking all the code of file demo.h
Are you sure you don't want to write
#ifndef DEMO_H
#define DEMO_H
....
#endif
[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

/Jorgen
 
B

Brian Casiello

Jorgen Grahn said:
On Jul 29, 9:36 am, Nephi Immortal <[email protected]> wrote:
[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual C++.

I suppose you could use both, and get the MS speed tweak and
portability.
 
P

Paul Brettschneider

Brian said:
Jorgen Grahn said:
On Jul 29, 9:36 am, Nephi Immortal <[email protected]> wrote:
[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual C++.

I'm pretty sure that Jorgen was being facetious and knows about this
proprietary extension.
I suppose you could use both, and get the MS speed tweak and
portability.

Have you actually done any speed measurements? One would think that include
guards are so common that any decent compiler would recognize them and treat
them exactly like this #pramga. Looks like a relic from the dark ages. :)
 
J

Jorgen Grahn

Brian said:
Jorgen Grahn said:
On Sat, 2011-07-30, MJ_India wrote:

[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual C++.

I'm pretty sure that Jorgen was being facetious and knows about this
proprietary extension.

I *suspected* it was a MS thing, but I had to look in the g++ manual
before posting.

/Jorgen
 
A

Alf P. Steinbach

Brian said:
On Sat, 2011-07-30, MJ_India wrote:

[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual C++.

I'm pretty sure that Jorgen was being facetious and knows about this
proprietary extension.

I *suspected* it was a MS thing, but I had to look in the g++ manual
before posting.

No, "#pragma once" is not an MS thing.

And as I'm testing now MinGW g++ 4.x supports "#pragma once".

It's a de facto standard: AFAIK the C++ standardization committee is the
only actor who has not adopted it.

<url: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8>
<url: http://en.wikipedia.org/wiki/Pragma_once>

However, the GNU docs references above says "#pragma once" is obsolete.

That's a pretty weird statement.


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

Brian Casiello wrote:


On Sat, 2011-07-30, MJ_India wrote:

[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual
C++.

I'm pretty sure that Jorgen was being facetious and knows about this
proprietary extension.

I *suspected* it was a MS thing, but I had to look in the g++ manual
before posting.

No, "#pragma once" is not an MS thing.

And as I'm testing now MinGW g++ 4.x supports "#pragma once".

It's a de facto standard: AFAIK the C++ standardization committee is the
only actor who has not adopted it.

<url: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8>
<url: http://en.wikipedia.org/wiki/Pragma_once>

However, the GNU docs references above says "#pragma once" is obsolete.

That's a pretty weird statement.

Oh, the more recent GNU docs, for version 4.6, do not say obsolete:

http://gcc.gnu.org/onlinedocs/gcc-4...ndef.html#Alternatives-to-Wrapper-_0023ifndef


Cheers & hth.,

- Alf
 
I

Ian Collins

No, "#pragma once" is not an MS thing.

And as I'm testing now MinGW g++ 4.x supports "#pragma once".

It's a de facto standard: AFAIK the C++ standardization committee is the
only actor who has not adopted it.

<url: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8>
<url: http://en.wikipedia.org/wiki/Pragma_once>

However, the GNU docs references above says "#pragma once" is obsolete.

That's a pretty weird statement.

Not really, the compiler can perform the same optimisations with include
guards.
 
P

Paul Brettschneider

wrote:
Oh, the more recent GNU docs, for version 4.6, do not say obsolete:

http://gcc.gnu.org/onlinedocs/gcc-4.6.1/cpp/Alternatives-to-Wrapper-
_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef

Isn't "[W]e recommend you do not use them in new programs" a mild form of
saying just that?

I have nothing against extensions (for example no_return or format string
specifiers in C-like IO functions are very useful), but if there is no
advantage over the standard way, I fail to see the point. Especially in this
case were it was suggested up-thread to use include guards *and* the
#pragma. That's one more line for nothing. Old cruft like this should be
supported for compatibility reasons, but also deprecated to make a point.
 
A

Alf P. Steinbach

wrote:
Oh, the more recent GNU docs, for version 4.6, do not say obsolete:

http://gcc.gnu.org/onlinedocs/gcc-4.6.1/cpp/Alternatives-to-Wrapper-
_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef

Isn't "[W]e recommend you do not use them in new programs" a mild form of
saying just that?

I have nothing against extensions (for example no_return or format string
specifiers in C-like IO functions are very useful), but if there is no
advantage over the standard way, I fail to see the point.

The pragma is generally safer than include guards, it gives less visual
clutter, and, being higher level, can even be faster.

The reason for the generally improved safety is that it does not rely on
the programmer selecting a truly unique header guard symbol.

There is one situation where instead include guards can be safer, namely
in the context of symbolic links to files. But that's a rare situation,
and mostly it's just a question of Quality of Implementation. g++ once
had a problem here, but it was fixed.

Especially in this
case were it was suggested up-thread to use include guards *and* the
#pragma. That's one more line for nothing. Old cruft like this should be
supported for compatibility reasons, but also deprecated to make a point.

On the contrary, "#pragma once" is probably what one should use for new
code -- IN SPITE OF NOT BEING FORMALLY STANDARD. ;-)


Cheers & hth.,

- Alf
 
J

Jorgen Grahn

On Sat, 2011-07-30, MJ_India wrote:

[Prefer to use #pragma once instead of ifndef guards]

That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's a Microsoft Visual-C++ thing, it means the header should only be
opened and read once. It's effectively equivalent to include guards and
may speed up compiles as long as you know your code is and will always
be VC++ specific (it depends on other Microsoft-isms), or if you
don't care that your code will only compile efficiently with Visual
C++.

I'm pretty sure that Jorgen was being facetious and knows about this
proprietary extension.

I *suspected* it was a MS thing, but I had to look in the g++ manual
before posting.

No, "#pragma once" is not an MS thing.

And as I'm testing now MinGW g++ 4.x supports "#pragma once".

It's a de facto standard: AFAIK the C++ standardization committee is the
only actor who has not adopted it.

<url: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8>
<url: http://en.wikipedia.org/wiki/Pragma_once>

However, the GNU docs references above says "#pragma once" is obsolete.

That's a pretty weird statement.

Oh, the more recent GNU docs, for version 4.6, do not say obsolete:

http://gcc.gnu.org/onlinedocs/gcc-4...ndef.html#Alternatives-to-Wrapper-_0023ifndef

Oh -- it didn't occur to me to look in the cpp manual (although it
should have).

I note though that (a) I've never seen it used, and (b) on my system
none of the 2800 files in /usr/include use it.

/Jorgen
 
M

Miles Bader

Jorgen Grahn said:
Oh -- it didn't occur to me to look in the cpp manual (although it
should have).

I note though that (a) I've never seen it used, and (b) on my system
none of the 2800 files in /usr/include use it.

It seems clear that, at least in portable code, the #ifdef... solution
is both idiomatic and the "safe choice" (will work in any compiler),
which seem a good reason to prefer it, especially considering it's
_also_ efficient with many common compilers (dunno about microsoft
compilers).

-Miles
 
J

James Kanze

1. #ifdef DEMO_H is masking all the code of file demo.h
Are you sure you don't want to write
#ifndef DEMO_H
#define DEMO_H
....
#endif
[Prefer to use #pragma once instead of ifndef guards]
That last sentence -- is that supposed to be an advice? I've never
seen anything other than the include guard stuff you described above.
And my compiler (g++) doesn't seem to have a pragma named "once".

It's very bad advice. (Although I seem to recall that #pragma
once does work with g++. G++ makes a certain effort to be
compatible with VC++---even to the point of being bug
compatible.) #pragma (regardless of which one) is only for
things which are only relevant to a single compiler.
 
J

James Kanze

Except for all of the others. Most of the C++ compilers I've
used in the past didn't support it. (The only C++ compilers I
use currently are VC++ and g++.)
<url:http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8>
<url:http://en.wikipedia.org/wiki/Pragma_once>
However, the GNU docs references above says "#pragma once" is obsolete.
That's a pretty weird statement.
Oh, the more recent GNU docs, for version 4.6, do not say obsolete:
http://gcc.gnu.org/onlinedocs/gcc-4.6.1/cpp/Alternatives-to-Wrapper-
_0023ifndef.html#Alternatives-to-Wrapper-_0023ifndef
Isn't "[W]e recommend you do not use them in new programs" a mild form of
saying just that?
I have nothing against extensions (for example no_return or format string
specifiers in C-like IO functions are very useful), but if there is no
advantage over the standard way, I fail to see the point.
The pragma is generally safer than include guards, it gives less visual
clutter, and, being higher level, can even be faster.

The pragma isn't nearly as safe as include guards, since it
doesn't work generally. If you want your code to be portable,
you need the include guards. And once you have the include
guards, the pragma doesn't buy you anything.

FWIW, the standards committee rejected it because it can't be
made to work reliably on networked machines. (I'm not sure I
agree with their decision. The cases where it doesn't work
reliably are pretty perverse, and would probably cause problems
for the humans managing the system. On the other hand, trying
to find standardese which let the implementation off the hook in
such cases doesn't seem trivial.)
The reason for the generally improved safety is that it does not rely on
the programmer selecting a truly unique header guard symbol.

That's a different problem. For starters, there's no reason why
the programmer should be selecting the guard symbol. That's the
environment's job, and it's relatively simple for the
environment to come up with something at least as unique as the
name of an unnamed namespace. I'm using vim, hardly the most
state of the art editor, and when I open a new .hh file, I get
the include guards already generated, with a lot of truly random
letters at the end.
There is one situation where instead include guards can be safer, namely
in the context of symbolic links to files. But that's a rare situation,
and mostly it's just a question of Quality of Implementation. g++ once
had a problem here, but it was fixed.

Symbolic links are easy, since you can resolve them to the true
name. Hard links are more difficult; you need to keep track of
the device and inode number. And remote mounted files are
impossible.
On the contrary, "#pragma once" is probably what one should use for new
code -- IN SPITE OF NOT BEING FORMALLY STANDARD. ;-)

Only if you don't care if your code works on machines other than
Windows and Linux.
 
M

Marc

James said:
#pragma (regardless of which one) is only for
things which are only relevant to a single compiler.

That may be true in C++, but it isn't in C which defines a number of
standard pragmas.
 
A

Alf P. Steinbach

Only if you don't care if your code works on machines other than
Windows and Linux.

I think, if one needs to support a compiler that doesn't support
`#pragma once`, then one is in about the same kind of boat as one who is
targeting a 16-bit char system: one is not writing portable code.

So, big difference between formal and practice. :)

But here's the crucial thing: if up-front generation of include guards
is feasible, and it is, then for those special compilers (like 16-bit
Digital Signal Processor compiler) it's no big deal to preprocess the
source replacing `#pragma once` with traditional include guards.

I.e. one accepts a little special-casing for the special case, to keep
the general case clean.

That's like having a sports car for general go-abouting, and bringing in
the help of e.g. tractor for plowing fields, where the sports car isn't
good tool. Using or bringing along the tractor in all cases, just
because it's needed in one special case that may or may not arise, well
that strikes me as awkward. :-O)

Cheers,

- Alf
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top