{"id":6191,"date":"2024-01-06T00:01:35","date_gmt":"2024-01-06T08:01:35","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6191"},"modified":"2024-01-13T10:03:43","modified_gmt":"2024-01-13T18:03:43","slug":"exploring-variable-integer-widths-in-c23","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6191","title":{"rendered":"Exploring Variable Integer Widths in C23"},"content":{"rendered":"<p>As C evolved, so did the definitions for integer sizes <em>short<\/em>, <em>int<\/em>, and <em>long<\/em>. Back when I first coded C, a <em>short<\/em> was 8-bits, an <em>int<\/em> was 16-bits, and a <em>long<\/em> was 32-bits. These values aren&#8217;t the same today or even consistent across platforms. This issue is addressed in the C23 standard by using the <em>_BitInt()<\/em> data type.<br \/>\n<!--more--><br \/>\nSome compilers have implemented work-arounds for the inconsistency with bits in an integer data type. For example, the <code>stdint.h<\/code> header file defines these data types, which I&#8217;ve <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4217\">written about<\/a> before:<\/p>\n<p><em>int8_t<\/em> is an 8-bit integer.<br \/>\n<em>int16_t<\/em> is a 16-bit integer.<br \/>\n<em>int32_t<\/em> is a 32-bit integer.<br \/>\n<em>int64_t<\/em> is a 64-bit integer.<\/p>\n<p>You can employ these data types to ensure bit widths are consistent, but the <em>_BitInt()<\/em> data type in C23 makes this consistency part of the language. Plus it adds flexibility to let you set nonstandard bit width values, such as 12 or 24.<\/p>\n<p>Unlike traditional C language data types, the <em>_BitInt(n)<\/em> type features an argument, <em>n<\/em>, which sets the bit width. For example, <code>_BitInt(16)<\/code> declares a 16-bit integer value. This value is consistently 16-bits regardless of the size of a <em>short<\/em>, <em>int<\/em>, or however else you could declare the variable.<\/p>\n<p>The value of <em>n<\/em> in <em>_BitInt(n)<\/em> must be declared as a constant or literal. Yes, I tried to use a variable and the compiler (<em>clang-15<\/em>) was smart enough to flag my attempt as an error.<\/p>\n<p>The maximum bit size you can declare when using the <em>_BitInt()<\/em> type is set by the <code>BITINT_MAXWIDTH<\/code> constant, defined in the <code>limits.h<\/code> header file.<\/p>\n<p>Like other integer data types, you can create a <em>signed<\/em> or <em>unsigned<\/em> <em>_BitInt()<\/em> value. The number of bits you specify always includes the sign bit, for <em>unsigned<\/em> values.<\/p>\n<p>The following code declares an 8-bit integer and outputs its value. The code also includes the <code>limits.h<\/code> header file to output the maximum bit width allowed for a <em>_BitWidth()<\/em> variable.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_01_06-Lesson.c\" rel=\"noopener\" target=\"_blank\">2024_01_06-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;limits.h&gt;\r\n\r\nint main()\r\n{\r\n    _BitInt(8) supershort;\r\n\r\n    supershort = 22;\r\n\r\n    printf(\"The 8-bit variable has a value of %d\\n\",(int)supershort);\r\n    printf(\"_BitInt(%d) uses %lu bytes in memory\\n\",\r\n            BITINT_MAXWIDTH,\r\n            sizeof(_BitInt(BITINT_MAXWIDTH))\r\n          );\r\n\r\n    return 0;\r\n}<\/pre>\n<p>For the first <em>printf()<\/em> statement, I typecast the <code>supershort<\/code> variable to an <em>int<\/em>. The program builds without the typecast, though it throws a warning as the compiler doesn&#8217;t accept that the <code>%d<\/code> placeholder matches a <em>_BitInt()<\/em> data type &mdash; and it&#8217;s correct. I don&#8217;t know of any placeholder specific to this new data type, so I typecast the variable to suppress the warning.<\/p>\n<p>Remember that the code must be built with the <code>-std=C2x<\/code> switch and with a compiler compatible with the C23 standard. Here&#8217;s the output:<\/p>\n<p><code>The 8-bit variable has a value of 22<br \/>\n_BitInt(128) uses 16 bytes in memory<\/code><\/p>\n<p>The first line doesn&#8217;t really confirm that the variable uses only 8-bits. But the second line shows the maximum value available for the <em>_BitInt()<\/em> data type on my machine.<\/p>\n<p>I tried creating super short integers &mdash; and it worked! The declaration <code>_BitInt(4)<\/code> creates a 4-bit signed integer value storing numbers in the range -8 through 7. My inner nerd is thrilled.<\/p>\n<p>The C23 standard also employs specific bit-width data types for real numbers:<\/p>\n<p><em>_Decimal32<br \/>\n_Decimal64<br \/>\n_Decimal128<\/em><\/p>\n<p>These data types are compliant with various IEEE standards. This addition is necessary as like integer data types, <em>float<\/em>, <em>double<\/em>, and <em>long double<\/em> may use different bit widths on different systems. These new data types ensure consistency across all platforms.<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6193\">next week&#8217;s Lesson<\/a> I cover a new method of initializing an array, one that will finally be consistent across all C23 compatible compilers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>C23 introduces a standard for setting exact bit widths for integer values. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6191\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6191","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6191"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6191\/revisions"}],"predecessor-version":[{"id":6213,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6191\/revisions\/6213"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}