Skip to content

Instantly share code, notes, and snippets.

@BenWiederhake
Last active January 10, 2023 23:52
Show Gist options
  • Save BenWiederhake/db2584a2ea307cefd7fe15710f5efd8d to your computer and use it in GitHub Desktop.
Save BenWiederhake/db2584a2ea307cefd7fe15710f5efd8d to your computer and use it in GitHub Desktop.
// g++ -O2 -std=c++20 -o foo repro.cpp && ./foo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Vector {
~Vector() {}
char* data() {
if (m_outline)
return m_outline;
return reinterpret_cast<char*>(m_inline);
}
char m_inline[32];
char* m_outline { nullptr };
};
static Vector make_vector() {
auto buffer = Vector();
unsigned new_size = 128;
auto* new_buffer = new char[new_size];
buffer.m_outline = new_buffer;
if (!new_buffer) return buffer; // !!!
for (unsigned i = 0; i < 128; ++i)
buffer.m_outline[i] = 0;
// This fixes the warning:
// if (!buffer.m_outline) __builtin_unreachable();
// The compiler thinks this will overflow. Why?!
memset(buffer.data(), 'A', new_size);
//> warning: ‘void* memset(void*, int, size_t)’ writing 128 bytes into a region of size 40 overflows the destination [-Wstringop-overflow=]
// Uncomment the following println() and it magically works, *and* shows that it uses the correct buffer. Huh?!
// printf("vector struct is initially at %p, first datum is at %p\n", &buffer, buffer.data());
return buffer;
}
int main() {
auto actual = make_vector();
printf("vector struct is later at %p, first datum is at %p\n", &actual, actual.data());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment