https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116909
Bug ID: 116909 Summary: Does g++ define the behavior for an "array" manually created with a linker script? Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: federico at kircheis dot it Target Milestone: --- Consider following program main.cpp ---- using test_signature = void(); void test2(){std::puts("test2");} [[gnu::used]] constexpr test_signature* const t1 [[gnu::section(".tests")]] = +[]{std::puts("test1");}; [[gnu::used]] constexpr test_signature* const t2 [[gnu::section(".tests")]] = test2; [[gnu::used]] constexpr test_signature* const t3 [[gnu::section(".tests")]] = test2; // eventually many other auto get_tests() noexcept { extern const test_signature* const tests_begin[]; extern const test_signature* const tests_end[]; return std::span<test_signature* const>(tests_begin, tests_end); } int main(){ auto funcs = get_tests(); for(const auto& v : funcs){ v(); } } ---- linkerscript.ld ---- SECTIONS { .tests : { PROVIDE(tests_begin = .); KEEP(*(.tests)) PROVIDE(tests_end = .); } } INSERT AFTER .text; ---- And compile it with "g++ --std=c++20 -Wl,-Tlinkerscript.ld main.cpp" The code works as expected (it calls the "registered functions" and prints whatever is passed to std::puts), at least on linux, tested with different optimizations flags (even with -flto and -fwhole-program), memory sanitizer and valgrind. I believe that the code triggers UB, because there is no array containing all functions pointers, thus one is not allowed to do pointer arithmetic. Since tests_begin and tests_end are created outside of C++, I guess there is little for the compiler to do except assume that there is an array, and thus I would like to claim that this code is portable between versions of gcc/ldd and platforms (please correct me if I am wrong. any suggestion on how to improve it or make more robust are welcome). Assuming my linker script is correct, does g++ specify the behavior of the program in this case? If not, does it make sense to define it? As the language does know nothing about "things" created outside of c++, it cannot specify the behavior, but the toolchain should be able to do so. I made the question for c++ with a c++ snippet, but the same question holds for C too.