Bug 43633 - sizeof returns wrong size for large long long values when using -std=c99
Summary: sizeof returns wrong size for large long long values when using -std=c99
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-04-02 23:00 UTC by Steve Ellcey
Modified: 2021-09-17 07:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steve Ellcey 2010-04-02 23:00:09 UTC
If I compile a program with -std=c99 and do a sizeof of a constant that is larger then LONG_LONG_MAX but smaller then ULONG_LONG_MAX I get 16 instead of 8.  For values larger then ULONG_LONG_MAX I get 8.  I can reproduce this on x86 Linux and IA64 HP-UX (and probably other systems).    Here is a test case that should show the problem on any systems where LONG LONG is 8 bytes.  Compiled without -std=c99 all the prints will print '8', with '-std=c99' the middle two prints will print out 16 instead of 8.  Reproducable with ToT and going back to at least 4.1.0.

#include <stdio.h>
main()
{
        /* LONG_LONG_MAX */
        printf("%ld\n", sizeof(9223372036854775807LL));
        /* LONG_LONG_MAX + 1 */
        printf("%ld\n", sizeof(9223372036854775808LL));
        /* ULONG_LONG_MAX as a long long type */
        printf("%ld\n", sizeof(18446744073709551615LL));
        /* ULONG_LONG_MAX + 1 as a long long type */
        printf("%ld\n", sizeof(18446744073709551616LL));
}
Comment 1 Andrew Pinski 2010-04-02 23:04:24 UTC
t.c:7:32: warning: integer constant is so large that it is unsigned
t.c:9:32: warning: integer constant is so large that it is unsigned
t.c:11:32: warning: integer constant is too large for its type
Comment 2 Andreas Schwab 2010-04-03 09:16:22 UTC
§6.4.4.1 Integer constants:

If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value. If all of the types in the list for the constant are signed, the extended integer type shall be signed.

Thus 9223372036854775808LL will be of some signed extended type, since it does not fit in long long.
Comment 3 Harald van Dijk 2010-04-05 12:54:56 UTC
(In reply to comment #2)
> §6.4.4.1 Integer constants:
> 
> If an integer constant cannot be represented by any type in its list, it may
> have an extended integer type, if the extended integer type can represent its
> value. If all of the types in the list for the constant are signed, the
> extended integer type shall be signed.
> 
> Thus 9223372036854775808LL will be of some signed extended type, since it does
> not fit in long long.

It *may* have an extended integer type. If it doesn't (and it doesn't: gcc doesn't have any of the standard's extended integer types, see http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Integers-implementation.html), such a constant is simply invalid, and gcc, after reporting that, is free to make the code behave however it likes. At least, as far as the standard is concerned.