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

Jan Pechanec jp at devnull.cz
Wed Mar 16 12:22:02 CET 2022


On Wed, 16 Mar 2022, Walter Herold Veedla wrote:

> 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.

Great that you figured that out!

While we can consider C a small language and 80-90% of it can be 
learned and used quite quickly, the rest may be tricky, possibly 
confusing at first sight and takes time to fully process.  However, 
most of that stuff works the way it does because how hardware works so 
it's worth spending time digging deeper.

Regards,
Jan

>
> 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
> _______________________________________________
> 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
>

-- 
Jan Pechanec <jp (at) devnull (dot) cz>
http://www.devnull.cz


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