Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does `std::format` require its arguments are aligned?

Consider the following code (godbolt link):

#include <format>
#include <iostream>

#pragma pack(push)
#pragma pack(1)
struct A {
    long l;
    int  n;
    char c;
};
#pragma pack(pop)

int main() {
    A arr[] = {{42, 42, 42}, {42, 42, 42}};
    std::cout << std::format("{} {} {}", arr[0].l, arr[0].n, arr[0].c); // ok
    std::cout << std::format("{} {} {}", arr[1].l, arr[1].n, arr[1].c); // error
}

The compile command is as follows:

clang-19 -std=c++23 -stdlib=libc++ -O3 -fsanitize=undefined

The runtime error is as follows:

runtime error: reference binding to misaligned address 0x7ffc995b2f3d for type 'long', which requires 8 byte alignment.

Why does std::format require its arguments are aligned?

like image 400
xmllmx Avatar asked Nov 22 '25 22:11

xmllmx


1 Answers

std::format takes its arguments by reference, and UB sanitizer detects it as UB because it will crash on platforms where the CPU cannot automatically fix unaligned loads and stores. see Load of misaligned address and UBsan finding

to fix the code you can pass temporaries to std::format instead

std::cout << std::format("{} {} {}", long{arr[0].l}, int{arr[0].n}, char{arr[0].c}); // ok
std::cout << std::format("{} {} {}", long{arr[1].l}, int{arr[1].n}, char{arr[1].c}); // ok

this is telling the compiler to create a temporary before passing it to the function, and this temporary should be aligned.

like image 153
Ahmed AEK Avatar answered Nov 24 '25 12:11

Ahmed AEK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!