1

I have a question: the size of a long double is 16 bytes, when I check that with sizeof() there is no problem, it returns 16 but I did this little program to fill a 16 byte string with zeros using a long double cast, but it fills only 10 bytes of zeros instead of 16, just two more than long and double, why does this happen?

#include <stdio.h>

int main(void)
{
    char s[17] = "aaaaaaaaaaaaaaaa";

    *((long double *)s) = 0.L;
    for (int i = 0; i < 16; i++)
        printf("%d", (int)s[i]);
    write(1, "\n", 1);
    return (0);
}

Output:

0000000000979797979797

Instead of:

0000000000000000

And for double it outputs well:

000000009797979797979797

So why does it work with double but not long double?

Fayeure
  • 1,181
  • 9
  • 21
  • 16 does not equal 17, which you need to store a 16 char string. – Paul Ogilvie Apr 11 '21 at 13:07
  • @PaulOgilvie I know my string is 17-length but the end byte is already `0` so this should fill the first 16 bytes too instead of 10 bytes – Fayeure Apr 11 '21 at 13:08
  • @PaulOgilvie Okay I unerstood what you meant, my bad it's `char s[17]` not `char s[16]`, edited – Fayeure Apr 11 '21 at 13:09
  • 1
    [Is long double in C++ an implementation of IEEE's binary128?](https://stackoverflow.com/q/52762881), [Why don't the authors of the C99 standard specify a standard for the size of floating point types?](https://stackoverflow.com/q/3444088), [Performance implications of long double. Why does C choose 64-bits instead of the hardware's 80-bit for its default?](https://stackoverflow.com/q/10256019) – phuclv Apr 11 '21 at 13:36
  • 1
    duplicate: [Size of long double on Intel](https://stackoverflow.com/q/21968474), [long double vs double](https://stackoverflow.com/q/3454576) – phuclv Apr 11 '21 at 13:44
  • 3
    `*((long double *)s)` is a [strict aliasing violation](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and is therefore undefined behavior. It also risks violating the alignment restrictions of [6.3.2.3 Pointers, paragraph 7](https://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p7): "A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined." Whoever or whatever is teaching you code like that is incompetent. Use something like `memcpy()`. – Andrew Henle Apr 11 '21 at 13:59

1 Answers1

4

That's because most implementations use only 80-bit (10 bytes) for long double representation (from Wikipedia):

On the x86 architecture, most C compilers implement long double as the 80-bit extended precision type supported by x86 hardware (generally stored as 12 or 16 bytes to maintain data structure alignment), as specified in the C99 / C11 standards (IEC 60559 floating-point arithmetic (Annex F)).

saeedkazemi
  • 321
  • 1
  • 5