C++14 Binary Literals
Overview
C++14 introduces binary literals with the 0b prefix, allowing integer constants to be written directly in binary form. This greatly improves readability in bit-operation-heavy code (hardware register configuration, protocol parsing, permission flags). Binary literals can be combined with constexpr for compile-time bitwise operations.
Syntax
cpp
0bbinary_digits // int type (at least 32 bits)
0Bbinary_digits // uppercase form, equivalent
0bbinary_digitsu // unsigned int
0bbinary_digitsl // long
0bbinary_digitsll // long long
0bbinary_digitsull // unsigned long longValid digits are 0 and 1.
Code Examples
Basic Usage
cpp
#include <iostream>
int main() {
int a = 0b1010; // 10
int b = 0B1111'0000; // 240 — using C++14 digit separator
unsigned c = 0b11111111u; // 255
std::cout << a << ' ' << b << ' ' << c << '\n';
// Output: 10 240 255
}Permission Flag Definitions
cpp
// Permission system — each bit represents a permission
constexpr int PERM_READ = 0b0001; // bit 0
constexpr int PERM_WRITE = 0b0010; // bit 1
constexpr int PERM_EXEC = 0b0100; // bit 2
constexpr int PERM_ADMIN = 0b1000; // bit 3
constexpr int PERM_ALL = 0b1111;
constexpr int PERM_NONE = 0b0000;
// Check permission
constexpr bool has_permission(int user_perm, int check) {
return (user_perm & check) == check;
}
// Compile-time verification
static_assert(has_permission(PERM_ALL, PERM_READ));
static_assert(has_permission(PERM_ALL, PERM_WRITE));
static_assert(!has_permission(PERM_READ, PERM_WRITE));Hardware Register Configuration
cpp
#include <cstdint>
// UART control register bit fields
constexpr uint8_t UART_ENABLE = 0b0000'0001; // bit 0: enable
constexpr uint8_t UART_TX_ENABLE = 0b0000'0010; // bit 1: transmit enable
constexpr uint8_t UART_RX_ENABLE = 0b0000'0100; // bit 2: receive enable
constexpr uint8_t UART_PARITY_EVEN = 0b0000'1000; // bit 3: even parity
constexpr uint8_t UART_STOP_BITS_2 = 0b0001'0000; // bit 4: 2 stop bits
constexpr uint8_t UART_DATA_8BIT = 0b0110'0000; // bit 6-5: 8-bit data
// Combined configuration
constexpr uint8_t UART_CONFIG_8N1 =
UART_ENABLE | UART_TX_ENABLE | UART_RX_ENABLE | UART_DATA_8BIT;
// 0b0110'0111 = 0x67
// Configuration function
constexpr uint8_t configure_uart(bool parity_even, bool stop_2) {
uint8_t cfg = UART_ENABLE | UART_TX_ENABLE | UART_RX_ENABLE | UART_DATA_8BIT;
if (parity_even) cfg |= UART_PARITY_EVEN;
if (stop_2) cfg |= UART_STOP_BITS_2;
return cfg;
}
static_assert(configure_uart(true, false) == 0b0000'1111);Network Subnet Masks
cpp
#include <cstdint>
constexpr uint32_t MASK_24 = 0b11111111'11111111'11111111'00000000; // /24
constexpr uint32_t MASK_16 = 0b11111111'11111111'00000000'00000000; // /16
constexpr uint32_t MASK_8 = 0b11111111'00000000'00000000'00000000; // /8
constexpr bool in_subnet(uint32_t ip, uint32_t subnet, uint32_t mask) {
return (ip & mask) == (subnet & mask);
}Bit Manipulation Utilities
cpp
#include <iostream>
#include <bitset>
// Templatized bit count (compile-time)
template <typename T>
constexpr int popcount(T value) {
int count = 0;
while (value) {
count += (value & 1);
value >>= 1;
}
return count;
}
static_assert(popcount(0b1010) == 2);
static_assert(popcount(0b1111'1111) == 8);
// Print binary representation
void print_binary(unsigned char byte) {
std::cout << std::bitset<8>(byte) << '\n';
}
int main() {
print_binary(0b1010'0101); // Output: 10100101
}Best Practices
- Use binary literals instead of hexadecimal for bit fields:
0b0010is more intuitive than0x2in bit-flag contexts. - Combine with digit separators for readability:
0b1111'0000'1010'0101grouped by bytes is much easier to review than the version without separators. - Prefer
constexprfor bitwise results: Compile-time computation eliminates runtime overhead and catches errors at compile time. - Watch type suffixes: Binary literals default to
int; for large values, addu,ull, or other suffixes to avoid sign issues. - Do not overuse binary literals: For simple values like
0,1,255, decimal or hexadecimal is more conventional and does not need to be changed to binary. - Pair with
std::bitset: For runtime debug printing,std::bitset<8>(value)can directly output a binary string.