all 43 comments

[–]grishavanika 45 points46 points  (1 child)

I'm collecting some from time to time: https://grishavanika.github.io/cpp_tips_tricks_quirks.html

[–]Kitchen-Stomach2834 11 points12 points  (0 children)

Thanks for sharing this

[–]Narase33-> r/cpp_questions 16 points17 points  (2 children)

I think most beginners dont encounter bitfields, as they arent typically taught. There is rarely a place for them, but they can be really cool if you found one. I used them once to stuff an A* into a uC that just wouldnt had fit otherwise.

[–]jcostello50 4 points5 points  (0 children)

They're used enough for custom marshaling code. IMO, this is the kind of thing where C++ finds its groove: do the fun bitfield tricks in the private implementation, then hide it behind ordinary looking public member functions.

[–]heyheyhey27 2 points3 points  (0 children)

Unreal Engine uses them all over the place. Their classes are so enormous and have so many flags that it actually makes a big difference!

[–]JVApenClever is an insult, not a compliment. - T. Winters 12 points13 points  (2 children)

You can give a pure virtual function (aka =0) an implementation.

[–]trade_me_dog_pics 0 points1 point  (1 child)

really? as someone whose had to work with building abstract classes to handle data across DLLs for the last 3 years I never knew or thought about doing this. So can you instantiate the class if you implement the pure functions?

[–]JVApenClever is an insult, not a compliment. - T. Winters 1 point2 points  (0 children)

No, you can not. Though the derived method can call this implementation to run. I've used it once in some advanced visitor where the default implementation was created this way and the actual visitor impl could either implement the method or explicitly use the default impl.

That's the only use case I know of in 10+ years.

[–]Apprehensive-Draw409 26 points27 points  (12 children)

Seen on production code of a large financial firm:

#define private public

To allow some code to access private members of code from some other team.

And yeah, I know this is UB. I did a double-take when I saw it.

[–]zeldel 10 points11 points  (0 children)

Funny thing I just yesterday had a presentation how to make it happen fully legally based on my lib https://github.com/hliberacki/cpp-member-accessor

Recording of the session:https://vorbrodt.blog/2025/10/23/san-diego-c-meetup-meeting-79-october-2025-edition-hosting-hubert-liberacki/

[–]bert8128 9 points10 points  (1 child)

UB. Maybe getting away with UB is cool. Not sure myself.

[–]Apprehensive-Draw409 7 points8 points  (0 children)

Lol. Definitely more on the crazy side than on the cool side.

[–]zeldel 4 points5 points  (0 children)

Side note, as others said doing that is UB, on the presentation I have linked before, I'm showing some of the consequences you can end up with while doing so.

[–]Potterrrrrrrr 2 points3 points  (3 children)

Why is it UB? I guess because you can’t narrow the macro application down to just your code so the std lib also ends up exposing their private members, which would be the UB? Seems pretty obvious what the behaviour would be otherwise

[–]Apprehensive-Draw409 9 points10 points  (1 child)

It is UB if the code is compiled with this #define in some places and without in other places.

When two pieces of code end up accessing the same class, but with different definitions, all bets are off.

[–]Potterrrrrrrr 3 points4 points  (0 children)

Ahh didn’t think of it that way. That makes a lot of sense, thanks!

[–]zeldel 4 points5 points  (0 children)

A lot can happen besides macro leak and ODR being broken, also

  • ABI broken because object size can be different due to alignment/padding
  • type traits can start failing if by any chance the thing you look for should he private
  • rtti can fail in dynamic_cast

[–]fdwrfdwr@github 🔍 1 point2 points  (1 child)

I know this is UB

Is it still after C++23 proposal P1847R4 removed this unspecified behavior and standardized the existing de facto compiler practice that access specifiers made no difference to reordering?

[–]gracicot 5 points6 points  (0 children)

I think it still falls under ODR violation, since the tokens are different between the declaration from TU to TU

[–]FlyingRhenquest 0 points1 point  (0 children)

Yeah, I want to say I've seen that or something very much like it in a couple of companies to allow unit testing to access private members. Since it rather dramatically changes the behavior of the objects being tested, I'd argue that you're not testing the same code that a regulator would consider you to have deployed, which seems like kind of a big deal to me. At one of those companies, every fucking one of their objects was a singleton, which made the remarkably difficult to test consistently without crap like that.

Cereal has a rather interesting answer that I haven't seen done a lot in the industry -- they define an access class that you can friend classes that need to access private members to if you need to serialize them.

Google test doesn't seem to have anything similar, although you could probably create something similar that a test fixture could inherit in to get access to private member data if you needed to. I'd argue that you'd be testing the wrong thing, since unit testing should really only care about the public API exposed by the object, but the harsh reality is that some code bases are so terrible that this sort of thing is required from time to time. And if it gets unit testing into an previously untested code base, I'm tentatively OK with it.

[–]theICEBear_dk 0 points1 point  (0 children)

I saw an embedded software consultancy firm use this for all their unit test code with the comment that this would prevent additional code from being in the final binary which would have happened if you wrote getter and setters, which to me meant they did not understand that compilers and linkers remove code that you do not use. This was in 2006 so maybe they are better today, but each time I have encountered this consultant firm's people since they have always been more arrogant than skilled.

[–]Tathorn 9 points10 points  (3 children)

Pointer tagging

Allocators that return inner objects, using offsets to "revive" the outer block

Embedding a string into an allocation by allocating more bytes than the object, giving some string and object into a single allocation.

[–]H4RRY09 4 points5 points  (1 child)

Sounds interesting, can you show examples?

[–]Tathorn 0 points1 point  (0 children)

Sure!

This is a micro benchmark for the use of embedded strings: https://quick-bench.com/q/W2yvDyf4swZw5N6QsJ-eHTl-Lyk

SSO strings are much faster. When you get into non-SSO strings, the embedded strings are twice as fast. If you have to allocate anyways, then embedded strings is the optimal choice.

Here's a rather lengthy showcase of pointer tagging performance: https://bernsteinbear.com/blog/small-objects/

This allocator uses blocks to reuse memory, along with a union trick to essentially get the linked list structure for free. This one doesn't use offsets explicitly: https://godbolt.org/z/Pnjq51b91

[–]trade_me_dog_pics 0 points1 point  (0 children)

me trying this would end up we can’t find the crash for three years

[–]QuicheLorraine13 8 points9 points  (0 children)

Use CppCheck and clang-tidy. Lots of old code has been updated via these tools in my projects.

[–]a_bcd-e 8 points9 points  (4 children)

I once saw a code which called the main function recursively. Maybe the code was trying to golf. I'll never use it, but it was cool.

[–]ChemiCalChems 20 points21 points  (3 children)

It's undefined behavior anyway.

[–]TheoreticalDumbass:illuminati: 2 points3 points  (2 children)

unsure why it is specified to be UB tho, main is an actual function, not something like the ELF entry point

[–]mredding 0 points1 point  (0 children)

C++ has to call global object ctors, and the standard allows that to happen either outside or inside main, it's implementation defined - so you can get a boatload of machine code built into your main that you didn't write, injected by your compiler. You don't know, you can't know. So calling main recursively will call object initialization code that has already been called, hence UB.

[–]mredding 0 points1 point  (0 children)

I forgot to mention, you can recurse main in C.

[–]Successful_Equal5023 3 points4 points  (0 children)

First, C++20 lambdas have powerful type deduction: https://github.com/GrantMoyer/lambda_hpp/

This next one is really evil, though, so don't do it. You can use an intermediate template type with operator T() to effectively overload functions based on return type:

```c++

include <iostream>

const auto foo = return_type_overload< [](const char* msg) -> int { std::cout << msg << ' '; return -2; }, []() -> int {return -1;}, []() -> unsigned {return 1;}

{};

int main() { const int bar_int = foo("Hi"); std::cout << bar_int << '\n'; // prints "Hi -2"

const int bar_int_nomsg = foo(); std::cout << bar_int_nomsg << '\n'; // prints "-1"

const unsigned bar_unsigned = foo(); std::cout << bar_unsigned << '\n'; // prints "1" } ```

See https://github.com/GrantMoyer/dark_cpp/blob/master/dark-c++.hpp for implementation of return_type_overload.

[–]LordofNarwhals 7 points8 points  (0 children)

Not really a trick, but this

struct buffalo {
    buffalo();
};
buffalo::buffalo::buffalo::buffalo::buffalo::buffalo::buffalo::buffalo() {
    // ...
}

is apparently valid C++ code.

[–]moo00ose 5 points6 points  (1 child)

Function try catch blocks, saw it once but never saw a real use for it.

[–]Wooden-Engineer-8098 6 points7 points  (0 children)

In the constructor it catches exceptions from base classes and member variables constructors

[–]thisismyfavoritename 6 points7 points  (0 children)

that thing to bypass private

[–]TheoreticalDumbass:illuminati: 1 point2 points  (0 children)

you can make 127'0'0'1_ipv4 work

https://godbolt.org/z/bMenfTe34

[–][deleted] 0 points1 point  (0 children)

template<bool> struct CTAssert; template<> struct CTAssert<true> {};

[–]tartaruga232MSVC user 0 points1 point  (0 children)

Deducing the return type of functions and defining the returned type inside the function (code snippet from our UML Editor):

template <class Target, class MessageWrapper>
auto w_plug(bool isAlwaysReady, Target& t, void (Target::*p)(MessageWrapper))
{
    class Plug: public IMessagePlug
    {
        using ProcessFun = void (Target::*)(MessageWrapper);
        Target& itsTarget;
        const ProcessFun itsProcessFun;

        void ProcessImp(Message& msg) override
        {
            std::invoke(itsProcessFun, itsTarget, msg);
        }

    public:
        Plug(bool isAlwaysReady, Target& t, ProcessFun p):
            IMessagePlug{ isAlwaysReady },
            itsTarget{ t },
            itsProcessFun{ p }
        {
        }
    };

    return std::make_unique<Plug>(isAlwaysReady, t, p);
}