I know this question is about Visual Studio, but I'm going to try to answer for as many compilers as I can (including Visual Studio)…
A decade later there is progress! As of Visual Studio 2019 MSVC still doesn't support anything like this (even though it's the most popular builtin/intrinsic), but as Pauli Nieminen mentioned above C++20 has likely
/ unlikely
attributes which can be used to create likely/unlikely macros and MSVC usually adds support for new C++ standards pretty quickly (unlike C) so I expect Visual Studio 2021 to support them.
Currently (2019-10-14) only GCC supports these attributes, and even then only applied to labels, but it is sufficient to at least do some basic testing. Here is a quick implementation which you can test on Compiler Explorer:
#define LIKELY(expr) \
( \
([](bool value){ \
switch (value) { \
[[likely]] case true: \
return true; \
[[unlikely]] case false: \
return false; \
} \
}) \
(expr))
#define UNLIKELY(expr) \
( \
([](bool value){ \
switch (value) { \
[[unlikely]] case true: \
return true; \
[[likely]] case false: \
return false; \
} \
}) \
(expr))
Edit (2022-05-02): MSVC 2022 supports C++20, including [[likely]]
/[[unlikely]]
, but generates absolutely terrible code for this (see the comments on this post)... don't use it there.
You'll probably want to #ifdef around it to support compilers that can't handle it, but luckily most compilers support __builtin_expect
:
- GCC 3.0
- clang
- ICC since at least 13, probably much longer.
- Oracle Development Studio 12.6+, but only in C++ mode.
- ARM 4.1
- IBM XL C/C++ since at least 10.1, probably longer.
- TI since 6.1
- TinyCC since 0.9.27
GCC 9+ also supports __builtin_expect_with_probability
. It's not available anywhere else, but hopefully one day… It takes a lot of the guesswork out of trying to figure out whether to use ilkely/unlikely or not—you just set the probability and the compiler (theoretically) does the right thing.
Also, clang supports a __builtin_unpredictable
(since 3.8, but test for it with __has_builtin(__builtin_unpredictable)
). Since a lot of compilers are based on clang these days it probably works in them, too.
If you want this all wrapped up and ready to go, you might be interested in one of my projects, Hedley. It's a single public-domain C/C++ header which works on pretty much all compilers and contains lots of useful macros, including HEDLEY_LIKELY
, HEDLEY_UNLIKELY
, HEDLEY_UNPREDICTABLE
, HEDLEY_PREDICT
, HEDLEY_PREDICT_TRUE
, and HEDLEY_PREDICT_FALSE
. It doesn't have the C++20 version quite yet, but it should be there soon…
Even if you don't want to use Hedley in your project, you might want to check the the implementations there instead of relying on the lists above; I'll probably forget to update this answer with new information, but Hedley should always be up-to-date.
We want people to use profile guided optimizations instead of annotating their code by hand. See
this blog postfor more info. Profile counts don't lie (or rather, they lie much less than users do).
– HowlandBOOST_LIKELY
andBOOST_UNLIKELY
– Neilla