[C-prog-lang-l] Arithmetic conversions and sizes of types in limits.h

Walter Herold Veedla walterheroldv at gmail.com
Wed Mar 16 11:43:56 CET 2022


Hello,

Indeed the integer constants list clarifies everything:)

-2147483648

The type of the decimal constant 2147483648 is long int as it cannot fit 
inside the integer range after which the unary minus is applied to it.  
Furthermore any integer constant (if it fits) is by default an int. This 
was also mentioned in notes 04.md already the week before.  I suppose I 
was confused by the name of the #define CHAR_MAX which I immediately 
considered as the type, which it clearly is not, but only something for 
the preprocessor to substitute with the value.

Thanks for clearing that up.

Kind regards

Walter


On 16.03.2022 07:40, Jan Pechanec wrote:
> On Tue, 15 Mar 2022, Walter Herold Veedla wrote:
>
>> Hello,
>>
>> I was thinking about the integer promotion topic that we talked about this
>> Monday and I think I have an interesting observation that was not explicitly
>> mentioned in class as well as a question.
>>
>> I dug around in limits.h
>> (https://opensource.apple.com/source/xnu/xnu-201/EXTERNAL_HEADERS/machine/limits.h.auto.html)
>> and noticed the asymmetric definition of INT_MAX and INT_MIN:
>>
>> #define  __INT_MAX__  2147483647
>> #define  INT_MIN  (-INT_MAX-1)
>>
>> Which puzzled me for a bit and made me think of the question why we do not
>> define
>>
>> #define  INT_MIN -2147483648
>>
>> instead? After all, this is the value you get when you print out INT_MIN. My
>> hunch is that what is mentioned in notes5.md under integer promotion (but this
>> is not integer *promotion*, is it?) is also happening here and the value
>> 2147483648 does not fit the value of integer due to the asymmetrical range of
>> two's complement and is first converted to long, before the unary minus is
>> applied. Is that correct?
>>
>>
>> Secondly, whereas INT_MAX and INT_MIN are defined in this asymmetric way,
>> CHAR_MIN, CHAR_MAX, SHRT_MIN, SHRT_MAX are not, see:
>>
>> #define  CHAR_MAX  127
>> #define  CHAR_MIN  (-128)
>> #define  SHRT_MAX  32767
>> #define  SHRT_MIN  (-32768)
>>
>> This is really strange, furthermore when printing the sizes of these quantities
>> they do not correspond to the sizes of the types, but even CHAR_MAX is 4 bytes.
>> See the following output:
>>
>> cc -std=c99 -Wall -Wextra -pedantic limits_test.c && ./a.out         |    1
>> #include <stdio.h>
>> sizeof(short)   = 2                                                  |    2
>> #include <limits.h>
>> sizeof(int)     = 4                                                  |    3
>> sizeof(long)    = 8                                                  |    4 int
>> INT_MAX = 2147483647  (4 bytes)                                      |    5
>> main(void)
>> 8 = sizeof(-2147483648) |    6 {
>> 4 = sizeof(-INT_MAX-1) |    7         printf("sizeof(short)\t= %zu\n",
>> sizeof(short));
>> |    8         printf("sizeof(int)\t= %zu\n", sizeof(int));
>> |    9         printf("sizeof(long)\t= %zu\n", sizeof(long));
>> SHRT_MAX = 32767  (4 bytes)                                          |   10
>> 4 = sizeof(-32768) |   11         // The below is -INT_MAX-1 written directly
>> 4 = sizeof(-SHRT_MAX-1) |   12         printf("INT_MAX = %d  (%zu bytes)\n",
>> INT_MAX, sizeof(INT_MAX));
>>                                                                       |
>> 13         printf("%zu = sizeof(-2147483648)\n", sizeof(-2147483648));
>>                                                                       |
>> 14         printf("%zu = sizeof(-INT_MAX-1)\n", sizeof(-INT_MAX-1));
>> CHAR_MAX = 127  (4 bytes)                                            |   15
>> 4 = sizeof(-32768) |   16         printf("\n\n");
>> 4 = sizeof(-SHRT_MAX-1) |   17
>>                                                                       |
>> 18         printf("SHRT_MAX = %d  (%zu bytes)\n", SHRT_MAX, sizeof(SHRT_MAX));
>>                                                                       |
>> 19         printf("%zu = sizeof(-32768)\n", sizeof(-32768));
>>                                                                       |
>> 20         printf("%zu = sizeof(-SHRT_MAX-1)\n", sizeof(-SHRT_MAX-1));
>>                                                                       | 21
>>                                                                       |
>> 22         printf("\n\n");
>>                                                                       | 23
>>                                                                       |
>> 24         printf("CHAR_MAX = %d  (%zu bytes)\n", CHAR_MAX, sizeof(CHAR_MAX));
>>                                                                       |
>> 25         printf("%zu = sizeof(-32768)\n", sizeof(-32768));
>>                                                                       |
>> 26         printf("%zu = sizeof(-SHRT_MAX-1)\n", sizeof(-SHRT_MAX-1));
>>                                                                       | 27 }
>>
>> What is going on here?
> Hi Walter,
>
> excellent observations, thank you for bringing that up.  Look at the
> following code and its results:
>
> janp:t490:~$ cat main.c
> #include <stdio.h>
> #include <limits.h>
>
> #define  MYINT_MIN -2147483648
> #define  MYINT_MIN2 (-INT_MAX - 1)
>
> int
> main(void)
> {
> 	printf("%zu\n", sizeof (MYINT_MIN));
> 	printf("%zu\n", sizeof (MYINT_MIN2));
> }
> janp:t490:~$ cc main.c
> janp:t490:~$ ./a.out
> 8
> 4
>
> Can you answer your questions now?
>
> Also see the C99 spec, 6.4.4.1 Integer constants.
>
> Cheers,
> Jan
>
>> If for some reason the output of the program arrives mis-formatted, I am also
>> attaching a .txt file of the output with this e-mail.
>>
>>
>> Anyways, I'd be happy to hear Your thoughts.
>>
>> Kind regards
>>
>> Walter Herold Veedla
>>
>>
>
> _______________________________________________
> c-prog-lang-l mailing list
> c-prog-lang-l at mff.cuni.cz
> http://mbox.ms.mff.cuni.cz/listserv/listinfo/c-prog-lang-l


More information about the c-prog-lang-l mailing list