Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define private to public in C++ [duplicate]

Tags:

c++

I want to define private and protected to public.

#define private public
#define protected public

Is this safe in C++?

like image 871
user4419862 Avatar asked Jan 05 '15 11:01

user4419862


3 Answers

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.

like image 57
Yakk - Adam Nevraumont Avatar answered Nov 16 '22 04:11

Yakk - Adam Nevraumont


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;
};
like image 6
molbdnilo Avatar answered Nov 16 '22 05:11

molbdnilo


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.

like image 3
Elemental Avatar answered Nov 16 '22 04:11

Elemental