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 #define
ing 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With