0

I was wondering whether I could initialize a pointer with constinit in C++20, and I didn't find any adequate answer on the internet. I have a simple code like this:

struct a {
    const char *s; // pointer I want to initialize
    int other_random_field; // This is another (useless in this case) field
};

constexpr struct a init(void)
{
    return {"foo", 4};
}
constinit struct a _ = init();

and compiles perfectly. However I don't see any way to make it work with any different type than char *. What if instead of "foo", I wanted to return an array of ints (whose size is known at compile time) or whatever?

So my real question is: Is there any way to call from my init() function a malloc()-like function which gives me the ability to write in a data-segment-allocated buffer?

BTW: The assembly gcc -std=gnu++20 produces is:

    .text
    .globl  _
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "foo"
    .section    .data.rel.local,"aw"
    .align 16
    .type   _, @object
    .size   _, 16
_:
    .quad   .LC0
    .long   4
    .zero   4

which is similar to what I want. But instead of putting .string "foo" I would like to put there, for example, an array of ints.

dVNE
  • 161
  • 9
  • 1
    I assume you want to create this "array of ints" dynamically at run-time, rather than as an actual array which is initialized at compile-time? – Some programmer dude May 15 '22 at 17:20
  • Does your buffer need to be dynamically sized, or is the size known at compile time? If the later, would just using a `std::array` fit your bill? – Brian61354270 May 15 '22 at 17:23
  • @Someprogrammerdude. As I have now specified, I would like to initialize it at compile time – dVNE May 15 '22 at 17:40
  • @Brian: For `constinit` to put it in the .data or .rodata section, it absolute must have a size known at compile time. Hopefully in a `constexpr` variable, which you can then use as a template parameter to `std::array`. That's what I was going to suggest, even if that size is calculated from some other constexpr variables. – Peter Cordes May 15 '22 at 17:42
  • What have you tried? What is the problems you have with your attempt? Have you tried just creating a plain and simple (global or static) array and make your pointer point to its first element, which is really what's being done with your literal string (as it's also a (global) array and you make `s` point to its first element). – Some programmer dude May 15 '22 at 17:50
  • As @Someprogrammerdude says, it fully works to constinit with a pointer to a global-scope `static constexpr int buf[4]`, as in https://godbolt.org/z/q7ba7na7o. That's the equivalent to what you're doing with a string literal. IDK why putting the `static constexpr` array inside the function scope makes it not work even with `-std=gnu++2b`. – Peter Cordes May 15 '22 at 17:57
  • @Someprogrammerdude. Can't a std::array be allocated from my `init()`function? That's my question. – dVNE May 15 '22 at 17:57
  • @PeterCordes. Ok. I've understood the thing that was troubling me. – dVNE May 15 '22 at 17:59
  • Does the struct you're initializing have to hold a pointer, instead of the array directly? Like `struct a { std::array arr; size_t size; };`? Hrm, maybe not; `std::array`'s type includes a length, so the struct type would then have to include `n`. Even if you did only use a pointer to a std::array object, the pointer type would include a size. Maybe use a std::array but then return it's `arr.data()` address so the size isn't encoded into the struct's type, only its data. – Peter Cordes May 15 '22 at 17:59

1 Answers1

1

You can do it with an int array or pointer as long as the address of it is known at compile time.

struct a {
    const int *s; // pointer I want to initialize
    int other_random_field; // This is another (useless in this case) field
};

int x[] = {1, 2};
constexpr struct a init(void)
{
    return {x, 4};
}
constinit struct a _ = init();
Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42