Products > Programming
GCC's __BIGGEST_ALIGNMENT__ macro on RISC-V architectures
ejeffrey:
BIGGEST_ALIGNMENT is the maximum alignment required by the ABI, not the architecture. So architectural flags aren't going to affect it unless it corresponds to a different ABI (riscv32 vs 64). That's going to be at least 8 bytes on most platforms that require double to be naturally aligned, and 16 bytes if it has a long double or long long type that requires it. This is independent of whether the architecture has hardware support for floating point or whether you actually link the soft math libraries.
If you want the machine native word size, use sizeof(void *).
Nominal Animal:
This can sound like a nitpick, but I warmly recommend writing that as sizeof (void *), with a space after the sizeof keyword, simply to remind us humans that it is not a function call and does not work like a function call; the expression is only evaluated for the type, without any side effects like memory accesses (or even pre- or post-increment and -decrement operations being applied).
The C language itself does not care either way, it's just for us humans.
SiliconWizard:
--- Quote from: ejeffrey on December 24, 2024, 06:40:37 pm ---If you want the machine native word size, use sizeof(void *).
--- End quote ---
If we're gonna nitpick further, problem is, whatever is meant by "native word size". Granted the OP was talking about RISC-V, in in this case, pointers will have the same size as all general-purpose registers, which I guess is what we could call "native word size" (backed by the numbering in RVxx). For other architectures, you can have different register sizes for different things, in particular address registers may have a different size than "data" registers. So 'sizeof (void *)' is not exactly a portable way of finding this out, and "native word size" isn't really a portable concept either.
If this is targetted at RISC-V specifically, rather than 'sizeof (void *)', I prefer using GCC's predefined macros (similarly available with Clang): __riscv_xlen, which give the XLEN value for the RISC-V target the code is compiled for (in bits! so, if you want the value in bytes, obviously just divide it by 8, it will be done at compile time for sure.)
Similarly, you have __riscv_flen for the width of the FP registers.
Just my 2 cents.
Of course, if you specifically want the size of *pointers* in a portable way, sizeof (void *) would do. Be again careful (although this is only found in niche architectures) that pointers to data and pointers to functions may have a different size.
As to the __BIGGEST_ALIGNMENT__ predefined macro, see: 'https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
As the name implies, it's the "largest alignment ever used for any data type on the target machine".
TheCalligrapher:
--- Quote from: HwAoRrDk on December 24, 2024, 09:47:56 am ---However, I have found that in code compiled for 32-bit RISC-V microcontrollers, this macro's value is 16. ??? I would have expected it to be 4. That is, I would expect it to reflect the architecture's (as specified by -march) native word/register size - 4 bytes for RV32, 8 bytes for RV64, etc.
--- End quote ---
That's unfounded, since the alignment requirements (including hardware-dicatated ones) are not generally tied to native word size. On x64, for one example, GCC's alignment requirement for `long double` values is 16, despite the native word size of 8. And there are x86 CPU instructions that will generate a bus error if fed with an unaligned `long double`.
Does 32-bit RISC-V GCC support any "over-aligned" types like that? BTW, as a wild guess, what is `long double` in 32-bit RISC-V GCC?
---
Just noticed that Godbolt offers 32-bit RISC-V GCC. So, let's try
--- Code: ---int x = alignof(long double);
int main() {}
--- End code ---
compiles to
--- Code: ---main:
li a0,0
ret
x:
.word 16
--- End code ---
So, here's your 16. It is indeed `long double` (at least). Not surprisingly, `alignof(std::max_align_t)` is also 16.
HwAoRrDk:
Oh, so it's an ABI thing, not something related to the specific -march being compiled for.
It'd probably help if they described it as such in the documentation, rather than the slightly ambiguous "target machine". Unless "target machine" has a more precise meaning that I'm not aware of within the lexicon of GCC...
Navigation
[0] Message Index
[*] Previous page
Go to full version