On the std-proposals list, the following code was given:
#include <vector>
#include <algorithm>
void foo(const std::vector<int> &v) {
#ifndef _ALGORITHM
std::for_each(v.begin(), v.end(), [](int i){std::cout << i; }
#endif
}
Let's ignore, for the purposes of this question, why that code was given and why it was written that way (as there was a good reason but it's irrelevant here). It supposes that _ALGORITHM is a header guard inside the standard header <algorithm> as shipped with some known standard library implementation. There is no inherent intention of portability here.
Now, _ALGORITHM would of course be a reserved name, per:
[C++11: 2.11/3]: In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2) and shall not be used otherwise; no diagnostic is required.
[C++11: 17.6.4.3.2/1]: Certain sets of names and function signatures are always reserved to the implementation:
Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
I was always under the impression that the intent of this passage was to prevent programmers from defining/mutating/undefining names that fall under the above criteria, so that the standard library implementors may use such names without any fear of conflicts with client code.
But, on the std-proposals list, it was claimed that this code is itself ill-formed for merely referring to such a reserved name. I can now see how the use of the phrase "shall not be used otherwise" from [C++11: 2.11/3]: may indeed suggest that.
One practical rationale given was that the macro _ALGORITHM could expand to some code that wipes your hard drive, for example. However, taking into account the likely intention of the rule, I'd say that such an eventuality has more to do with the obvious implementation-defined* nature of the _ALGORITHM name, and less to do with it being outright illegal to refer to it.
* "implementation-defined" in its English language sense, not the C++ standard sense of the phrase
I'd say that, as long as we're happy that we are going to have implementation-defined results and that we should investigate what that macro means on our implementation (if it exists at all!), it should not be inherently illegal to refer to such a macro provided we do not attempt to modify it.
For example, code such as the following is used all over the place to distinguish between code compiled as C and code compiled as C++:
#ifdef __cplusplus
extern "C" {
#endif
and I've never heard a complaint about that.
So, what do you think? Does "shall not be used otherwise" include simply writing such a name? Or is it probably not intended to be so strict (which may point to an opportunity to adjust the standard wording)?
Whether it's legal or not is implementation-specific (and identifier-specific).
When the Standard gives the implementation the sole right to use these names, that includes the right to make the names available in user code. If an implementation does so, great.
But if an implementation doesn't expressly give you the right, it is clear from "shall not be used otherwise" that the Standard does not, and you have undefined behavior.
The important part is "reserved to the implementation". It means that the compiler vendor may use those names and even document them. Your code may then use those names as documented. This is often used for extensions like __builtin_expect, where the compiler vendor avoids any clash with your identifiers (that are declared by your code) by using those reserved names. Even the standard uses them for things like __attribute__ to make sure it doesn't break existing (legal) code when adding new features.
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1882
Each identifier that contains a double understore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
any use. (similar text occurs both before and after that defect fix is applied)
__cplusplus is defined by the standard. _ALGORITHM is reserved by the standard to be used by implementations. These seem quite different? (The two sections of the standard do conflict, in that one states that __cplusplus is reserved for any use, and another uses it specifically, but I think that the winner of that conflict is clear).
The _ALGORITHM identifier could, under the standard, be used as part of a pre-processing step to say "replace this source code with hard drive deleting code". Its existence (prior to pre-processing, or after) could be sufficient to completely change your program behavior.
Now this is unlikely, but I do not think it results in an non-conforming implementation. It is a matter of quality of implementation only.
An implementation is free to document and define what _ALGORITHM means. For example, it could document that it is a header guard for <algorithm>, and indicates if that header file has been included. Treating your current <algorithm> implementation as documentation is probably going to far.
I'd guess using __cplusplus in C mode is technically "just as bad" as using _ALGORITHM, but this question is a c++ question, not a c question. I haven't delved into the c standard to look for quotes about it.
The names in [cpp.predefined] are different. Those have a specified meaning, so an implementation can't reserve them for any use, and using them in a program has a well-defined portable meaning. Using an implementation-specific identifier like the example of _ALGORITHM is ill-formed because it violates a shall-rule.
Yes, I'm fully aware of multiple examples where the library specification uses "shall" to mean "this is a requirement on user code, and violations are UB, not ill-formed".
Regarding whether it's UB or implementation-defined, running an ill-formed program results in UB. The standard wording clearly says the program is ill-formed, UB occurs if the implementation still chooses to accept the program and run it.
So, if a program uses the identifier _ALGORITHM, that program is ill-formed, and running such a program is UB, but that does not mean it doesn't work fine on an implementation that uses _ALGORITHM as an include guard, nor does it mean that it doesn't work fine on an implementation that doesn't.
If users are concerned about such ill-formedness and potential UB, and said users want to write portable C++, they shouldn't use reserved identifiers in portable C++ programs. If users accept that regardless of the standard prohibiting such a use, no practical implementation will wipe your hard drive, they can freely use such reserved identifiers, but by the letter of the standard, such uses are still ill-formed.
Historically, the purpose for making the use of such tokens "undefined behavior" is that compilers are free to attach any meaning they want to any such token that are not defined within the C standard. For example, on some embedded processors, using __xdata as a storage class for a variable will ask that it be stored in an area of RAM which is slower to access than the normal variable-storage area, but is much larger. On typical processors of that family, storage for "normal" variables would be limited to about 100 bytes, but storage for xdata variables may be much larger--up to 64K. The standard says basically nothing about what compilers are allowed to do with such directives, although typically (I'm not sure if the standard mandates this behavior, though I'm unaware of compilers violating it) such tokens are generally ignored within code that is disabled using a #if or similar directives.
Some libraries' header files will start their own internal identifiers with something that starts with two underscores but includes a pattern that's unlikely to be used by a compiler for any purpose (e.g. version 23 of the Foozle library might precede its identifiers with use __FZ23). It would be perfectly legitimate for a future compilers to use identifiers starting with __FZ23 for other purposes, and if that were to happen the Foozle library would need to be changed to use something else. If, however, it is likely that a major compiler upgrade would likely necessitate rewrites of the Foozle library for other reasons anyway, that risk may be acceptable compared to the risk of identifiers conflicting with outside code.
Note also that some project header files which are targeted toward a processor that requires __ directives may conditionally define macros with those names when compiled for other processors, for example:
#ifndef USE_XDATA
#define __XDATA
#endif
though a somewhat better pattern would generally be:
#ifdef USE_XDATA
#define XDATA __XDATA
#else
#define XDATA
#endif
When writing new code, the latter pattern is often better, but the former pattern may sometimes be useful when adapting existing code written on a platform that requires __XDATA so that it may be used both on platforms that use/require that directive and on platforms that do not.
Whether or not it is legal is a matter of local law. Whether it means anything, and if so, what, is a matter for the language definition. When you use a name that's reserved to the implementation the behavior of your program is undefined. That means that the language definition does not tell you what the program does. Nothing more, nothing less. If the compiler you're using documents what a particular reserved identifier does, then you can use that identifier with that compiler. If you hunt through headers and guess what various un-documented identifiers mean you might be able to use them, but don't be surprised if your code breaks when a subsequent update changes something.
Don't get hung up on __cplusplus. It's core language, and the stuff about double underscores, etc. is library. If that's not convincing, just consider it a glitch. You can use __cplusplus in C++ programs; its meaning is well defined.
Related
NOTE: This is a c question, though I added c++ in case some C++ expert can provide a rationale or historical reason why C++ is using a different wording than C.
In the C standard library specification, we have this normative text, C17 7.1.3 Reserved identifiers (emphasis mine):
All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
Now I keep reading answers on SO by various esteemed C experts, where they claim it is fine for a compiler or standard library to use identifiers with underscore + uppercase, or double underscore.
Doesn't "reserved for any use" mean reserved for anyone except future extensions to the C language itself? Meaning that the implementation is not allowed to use them.
While the second phrase above, regarding single leading underscore seems to be directed to the implementation?
In general, the C standard is written in a way that expects compiler vendors/library implementers to be the typical reader - not so much the application programmers.
Notably, C++ has a very different wording:
Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
(See What are the rules about using an underscore in a C++ identifier?)
Is this perhaps a mix-up between C and C++ and the languages are different here?
In the C standard, the meaning of the term "reserved" is defined by 7.1.3p2, immediately below the bullet list you are quoting:
No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
Emphasis mine: reserved identifiers place a restriction on the program, not the implementation. Thus, the common interpretation – reserved identifiers may be used by the implementation to any purpose – is correct for C.
I have not kept up with the C++ standard and no longer feel qualified to interpret it.
While the Standard is primarily written to guide implementers, it is written as a description of what makes a program well-formed, and what its effect is. That's because the basic definition of a standards-conforming compiler is one that does the correct thing for any standards-conforming program:
A strictly conforming program shall use only those features of the language and library
specified in this International Standard....A conforming
hosted implementation shall accept any strictly conforming program.
Read separately, this is hugely restrictive of extensions to a compiler. For instance, based solely on that clause, a compiler shouldn't get to define any of its own reserved words. After all, any given word a particular compiler might want to reserve, could nevertheless show up in a strictly conforming program, forcing the compiler's hand.
The standard goes on, however:
A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any strictly conforming
program.
That's the key piece. Compiler extensions need to be written in such a way that they affect nonconforming programs (ones which contain undefined behavior, or which shouldn't even compile at all), allowing them to compile and do fun extra things.
So the purpose of defining "reserved identifiers", when the language doesn't actually need those identifiers for anything, is to give implementations some extra wiggle room by providing them with some things which make a program nonconforming. The reason a compiler can recognize, say, __declspec as part of a declaration is because putting __declspec into a declaration is otherwise illegal, so the compiler is allowed to do whatever it wants!
The importance of "reserved for any use", therefore, is that it leaves no question about a compiler's power to treat such identifiers as having any meaning it cares to. Future compatibility is a comparatively distant concern.
The C++ standard works in a similar way, though it's a bit more explicit about the gambit:
A conforming implementation may have extensions (including additional library functions), provided they do
not alter the behavior of any well-formed program. Implementations are required to diagnose programs that
use such extensions that are ill-formed according to this International Standard. Having done so, however,
they can compile and execute such programs.
I suspect the difference in wording is down to the C++ standard just being clearer about how extensions are meant to work. Nevertheless, nothing in the C standard precludes an implementation from doing the same thing. (And we all basically ignore the requirement that the compiler warn you every time you use __declspec.)
Regarding the difference in wording in C versus C++, I'm posting my own little research here as reference:
The early K&R C 1st edition has this text:
...names which are intended for use only by functions of the library begin with an underscore so they are less likely to collide with names in a user's program.
K&R 2nd edition added an Appendix B which addresses the standard library, where we can read
External identifiers that begin with an underscore are reserved for use by the library, as are all
other identifiers that begin with an underscore and an upper-case letter or another underscore.
Early ANSI C drafts, as well as "C90" ISO 9899:1990, has the same text as in the current ISO standard.
The earliest C++ drafts however, has a different text, as noted by #hvd, possibly a clarification of the C standard. From DRAFT: 20 September 1994:
17.3.3.1.2 Global names
...
Each name that begins with an underscore and either an uppercase letter or another underscore (2.8) is
reserved to the implementation for any use
So apparently the wording "reserved for any use" was invented by the ANSI/ISO C90 committee, whereas the C++ committee some years later used a clearer wording, similar to the wording in the pre-standard K&R book.
The C99 rationale V5.10 says this below 7.1.3:
Also reserved for the implementor are all external identifiers beginning with an underscore, and
all other identifiers beginning with an underscore followed by a capital letter or an underscore.
This gives a name space for writing the numerous behind-the-scenes non-external macros and
functions a library needs to do its job properly.
This makes the committee's intention quite clear: "reserved for any use" means "reserved for the implementor".
Also of note, the current C standard has the following normative text elsewhere, in 6.2.5:
There may also be
implementation-defined extended signed integer types. 38)
where the informative foot note 38 says:
Implementation-defined keywords shall have the form of an identifier reserved for any use as
described in 7.1.3.
C has multiple contexts in which a symbol can have a definition:
The space of macro names,
The space of formal names of arguments to a macro (this space is specific to each function-like macro),
The space of ordinary identifiers,
The space of tag names,
The space of labels (this space is specific to each function), and
The space of structure/union members (this space is specific to each struct/union).
What "reserved for any use" means that the user code in a compliant program cannot use1 symbols that start with an underscore that is followed by an uppercase letter or another underscore in any of the above contexts. Compare with identifiers that start with a single underscore but are followed by a lowercase number or a digit. This falls into the second class of identifiers that start with an underscore. User code can can be use these identifiers as the names of macro arguments, as labels, or as the names of structure/union members.
"Reserved for any use" does not mean that the implementation cannot use such symbols. The intent of the reservation is to provide a name space that implementations can freely use without concern that the names defined by the implementation will conflict with the names defined by the user code in a compliant program.
1The standard does not quite mean "cannot use". The standard encourages the programmatic use of a small number of names that start with a double underscore. For example, a compliant implementation is required to define __STDC_VERSION__, __FILE__, __LINE__, and __func__. The 2011 version of the standard even gives an example of a presumably compliant program that references __func__.
The C Standard allows implementations to attach any meaning they see fit to reserved identifiers. Most implementations will treat unrecognized identifiers of reserved forms the same as any other recognized identifiers when there is no reason to do otherwise, thus allowing something like:
#ifdef __ACME_COMPILER
#define near __near
#else
#define near
#endif
int near foo;
to declare an identifier foo using a __near qualifier if the code is being processed in an Acme compiler (which would presumably support such a thing), but also be compatible with other compilers that would not require or benefit from the use of such a directive. Nothing would forbid a conforming implementation from defining __ACME_COMPILER and interpreting __near to mean "launch nuclear missiles", but a quality implementation shouldn't go out of its way to break code like the above. If an implementation doesn't know what __ACME_COMPILER is supposed to mean, treating it like any other unknown identifier would allow it to support useful constructs like the above.
It is months late but one point remains the others have not addressed.
Your question can be viewed from the opposite direction. The standard allows the implementation (as you have observed) to use a symbol like _Foo but, more importantly, thereby forbids the implementation from using foo. The latter is reserved for your use.
To understand, for discussion's sake, suppose that a future C standard introduced the new keyword _Foo. The hypothetical implementation was already using this symbol, so what happens?
Answer:
At first, the implementation will not yet have implemented the new standard. Until implemented, the new standard lacks practical effect.
Later, as part of implementing the new standard, the implementation quietly changes each _Foo to _Bar.
No problem.
In fact, if you think about it in this manner, you can say that the way the standard reserves such words is almost the only way it could reserve them.
Reading the anwser from What are the rules about using an underscore in a c identifier I stumbled across the follwing quotation:
From the 2003 C++ Standard:
17.4.3.2.1 Global names [lib.global.names]
Certain sets of names and function signatures are always reserved to the implementation:
Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.165
165) Such names are also reserved in namespace ::std (17.4.3.1).
What exactly is meant with reserved for the implementation?
Means exactly this. It means, that you are only allowed to create such names if you are providing a compiler or standard library implementation.
The "implementation" refers to the "implementation of the C++ language". It consists of everything needed to execute a C++ program: A compiler, a standard library, hardware on which to execute, an operating system, a visualization system, input, etc.
The restriction in question means that your compiler may predefine names of the reserved form without telling you, or your standard library implementation may do so. For example, your standard library may define a macro __Foo, so if you tried to use __Foo as an identifier in your source code, you'd actually end up with the macro replacement.
The purpose of reserved names is to give your compiler and standard library freedom to express functionality in plain C++ without worrying about introducing name clashes with user code.
For a vivid example of how this is used in practice, just look at any header file of your standard library implementation.
Some reserved names have actually been made into well-defined, publicly available facilities: __FILE__, __cplusplus, __VA_ARGS__, to name a few. The C language (which has the same rules for reserved identifies) has been using reserved names exclusively to introduce new keywords (e.g. _Bool).
Implementation here means the combination of compiler(say gcc, msvc and so on), the standard library (says what features are included in the language), Operating System(Windows, Mac etc) and hardware(Intel,ARM and so on).
Depending upon the implementation, certain values are defined which the compiler uses to produce the object code that is specific to the implementation. For example
__TARGET_ARCH_ARM is defined by RealView #Matches first case
_M_ARM is defined by Visual Studio #Matches second case
to identify the CPU manufacturer.
In short these clauses are meant to discourage you from using macros of mentioned format.
In fact, n3797->17.6.5.3 Restrictions on macro definitions says, if you wish to define macros of the aforementioned formats they are :
suitable for use in #if preprocessing directives, unless explicitly
stated otherwise.
Example :
#ifndef _M_ARM
#define _M_ARM // Say you're compiling for another platform
#endif
Note
Macros, reserved for implementation, are not restricted to the format mentioned in question. For instance __arm__ is defined by gcc to identify the manufacturer.
This question already has answers here:
C++ preprocessor #define-ing a keyword. Is it standards conforming?
(3 answers)
Closed 8 years ago.
I want to define private and protected to public.
#define private public
#define protected public
Is this safe in C++?
No, this almost certainly results in undefined behaviour.
From n4296 17.6.4.3.1 [macro.names] /2: (via #james below)
A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 2, or to the attribute-tokens described in 7.6.
private and public are keywords. Simply doing a #define on one of them is undefined behavior if you use anything in the C++ standard library:
17.6.4.1/1 [constraints.overview]
This section describes restrictions on C ++ programs that use the facilities of the C++ standard library.
If you do not, the restriction in 17.6.4.3.1 does not seem to apply.
The other way it could lead to violation is if you use the same structure with two different definitions. While most implementations may not care that the two structures are identical other than public vs private, the standard does not make that guarantee.
Despite that, the most common kind of UB is 'it works', as few compilers care.
But that does not mean it is 'safe'. It may be safe in a particular compiler (examine the docs of said compiler: this would be a strange guarantee to give, however!). Few compilers (if any) will provide the layout guarantees (and mangling guarantees) required for the above to work explicitly if you access the same structure through two different definitions, for example, even if the other possibilities of error are more remote.
Many compilers will 'just work'. That does not make it safe: the next compiler version could make one of a myriad of changes and break your code in difficult (or easy) to detect ways.
Only do something like this if the payoff is large.
I cannot find evidence that #defineing a keyword is undefined behavior if you never include any standard library headers and do not use it to make a definition different in two compilation units. So in a highly restricted program, it may be legal. In practice, even if it legal, it still isn't 'safe', both because that legality is extremely fragile, and because compilers are unlikely to test against that kind of language abuse, or care if it leads to a bug.
The undefined behavior caused by #define private foo does not seem to be restricted to doing it before the #include of the std header, as an example of how fragile it is.
It is allowed only in a translation unit that doesn't in any way (even indirectly) include a standard header, but if you do there are restrictions such as this:
(17.6.4.3.1) A translation unit shall not #define or #undef names lexically identical to keywords [...]
Regardless of that, it's usually a bad idea - mucking around with access modifiers isn't "safe" by any common meaning of the word, even if it won't cause any immediate problems in itself.
If you're using library code, there are usually good reasons for things being protected.
If you want to make things public temporarily, e.g. for testing purposes, you could use a special conditional macro for that part of the class:
#if TESTING
#define PRIVATE_TESTABLE public
#else
#define PRIVATE_TESTABLE private
#endif
class Foo
{
public:
Foo();
void operation();
PRIVATE_TESTABLE:
int some_internal_operation();
private:
int some_internal_data;
};
There is nothing illegal about doing this, it's just crazy.
You have to use this definition for all the compilation units (otherwise you might get the linker failing because of the name mangling.
If you are asking out of curiosity then this is perfectly legal (if confusing) c++; if you are asking because you think this is a good idea so you don't have all those pesky access permissions then you are on a very bad path. There a specific semantic reasons for using protected and private which serve to reduce he complexity of code and explain the 'contract' that modules have with each other. Using this define makes you code nearly unreadable for practiced c++ programmers.
Syntax is correct but semantic is wrong.
Access modifiers are for humans only so that you by accident don't use a method or field etc. that you are not supposed to access/change.
You could as well always make everything public if you write new code but in old code it can definitely break something. It would work but it would of course also be more error prone. Imagine what IntelliSense would suggest if you had access to everything everytime. Access modifiers don't only protect code that could break something if you used it in a wrong way but it helps IntelliSense to show you only members that are relevant in a particular context.
In C++ (and C) we have the #pragma directive which basically has implementation defined effects. However, are there any limits of what the directive may do? (Note that I'm asking about what the standard allows, not about what real compilers actually do.)
What I'm certain #pragma may do:
Allow to select one of several compilation options which all result in valid C++- For example, select one of several available ABIs, or switch certain implementation defined options.
What I would guess is allowed, but am not sure:
Allow the compiler to accept otherwise illegal code without issuing a diagnostic (for example, a compiler might decide to support a new built-in type long long long, but any code using that would have to issue a diagnostic; this diagnostic could then be suppressed with e.g. #pragma long long long.
Allow the compiler to reject otherwise legal code, for example there could be a #pragma strict which causes the compiler to flag as error the use of certain library functions and/or language constructs which are considered unsafe.
What I actually doubt is allowed, but am not sure either:
Allow the compiler to change the semantics of legal code to something different (for example, assume that a compiler vendor considered it a good idea if the for condition were a postcondition (as in do … while), and defined #pragma for postcondion to switch the meaning of for accordingly.
The reason why I doubt the latter is that the compiler is allowed to ignore any pragma it doesn't recognize, and therefore a change in semantics by a pragma would cause the same program to have different semantics on different compilers.
However, what does the standard actually allow? And are there things which are allowed, but which are not covered by my list above?
The standard is pretty clear on that:
[cpp.pragma] A preprocessing directive of the form
#pragma pp-tokensopt new-line
causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored.
The compiler can thus do pretty much whatever it wants on seeing a #pragma.
The n3337 version of C++ standard says
A preprocessing directive of the form
#pragma pp-tokensopt new-line
causes the implementation to behave in an implementation-defined manner.
The behavior might cause translation to fail or cause the translator or
the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored.
I think that allows the compiler to do almost anything it would like to do in case of a #pragma. Both the "translation to fail" and "translator or resulting program to behave in non-conforming manner" covers a great range of options.
That, of course, doesn't mean that it's a wise thing to allow the compiler to do "crazy" things - it may "upset" people, but it's perfectly valid from the standard's perspective.
The compiler is allowed to do absolutely everything, as long as it is documented. A really old version of gcc, upon seeing any pragma, used to stop compilation and attempted to locate and launch one of the text-mode games that existed back then. Which was perfectly standard conforming because there was a section about it in the user guide.
I understand that in C++ double underscores in identifiers are reserved for the compiler. I have some C code which has characteristics similar to this in the corresponding header files:
extern "C" {
#define HELLO__THERE 1
int hello__out__there( int );
}
I will be using this header in a C++ project, and plan to be doing things in C++ like:
if (HELLO__THERE == abc)
hello__out__there(foo);
Is this acceptable behavior in C++, covered by the standard?
In the C++03 standard 17.4.3.1.2 Global names, that use of underscores is defined as reserved:
Each name that contains a double underscore (_ _) or begins with an underscore followed by an upper-
case letter (2.11) is reserved to the implementation for any use.
Being reserved means that it might be used in any conforming implementation and therefore it is not advisable to use it.
You should be fine, unless by some fluke chance that one of the defines has clashes with your compiler's one. If that is the case, it'll likely be a warning or error (depending on your compiler's configuration) that there'll be a duplicate symbol.
Hope it helps. Cheers!
The method call would be OK but why compare HELLO_THERE to some value abc? If you were testing to see if a method was there I would wrap it in #ifdef ... #endif instead because if hello_out_there is not defined for some reason that would be a compile error.
double underlines in identifiers are reserved for the compiler
First, it's underscore I guess. Second such identifiers are reserved. That doesn't hold one back to not use it. You can use it (until there is no naming conflict).
Is this acceptable behavior in C++, covered by the standard?
Yes. It's acceptable. However, there is difference between acceptable and good code. If you are following a proper coding guidelines then your code will be good as well as acceptable. IMHO, you should refer to some good coding standards on internet; it will help you a lot.