{"id":1070,"date":"2022-08-30T15:11:53","date_gmt":"2022-08-30T15:11:53","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/is-unsigned-char-a45-a17-undefined-behavior-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:11:53","modified_gmt":"2022-08-30T15:11:53","slug":"is-unsigned-char-a45-a17-undefined-behavior-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/is-unsigned-char-a45-a17-undefined-behavior-collection-of-common-programming-errors\/","title":{"rendered":"Is unsigned char a[4][5]; a[1][7]; undefined behavior?-Collection of common programming errors"},"content":{"rendered":"<p>A compiler vendor who wants to write a conforming compiler is bound to what the Standard has to say, but not to your reasoning. The Standard says that an array subscript out of range is undefined behaviour, <strong>without any exception<\/strong>, so the compiler is allowed to blow up.<\/p>\n<p>To cite my comment from our last discussion (http:\/\/stackoverflow.com\/questions\/2832970\/does-c99-guarantee-that-arrays-are-contiguous)<\/p>\n<p>&#8220;Your original question was for <code>a[0][6]<\/code>, with the declaration <code>char a[5][5]<\/code>. This is UB, no matter what. It is valid to use <code>char *p = &amp;a[3][4];<\/code> and access <code>p[0]<\/code> to <code>p[5]<\/code>. Taking the address <code>&amp;p[6]<\/code> is still valid, but accessing <code>p[6]<\/code> is outside of the object, thus UB. Accessing <code>a[0][6]<\/code> is outside of the object <code>a[0]<\/code>, which has type array[5] of chars. The type of the result is irrelevant, it is important how you reach it.&#8221;<\/p>\n<p>EDIT:<\/p>\n<p>There are enough cases of undefined behaviour where you have to scan through the whole Standard, collect the facts and combine them to finally get to the conclusion of undefined behaviour. This one is <strong>explicit<\/strong>, and you even cite the sentence from the Standard in your question. It is explicit and leaves no space for any workarounds.<\/p>\n<p>I&#8217;m just wondering how much more explicitness in reasoning do you expect from us to become convinced that it really is UB?<\/p>\n<p>EDIT 2:<\/p>\n<p>After digging through the Standard and collecting information, here is another relevant citation:<\/p>\n<blockquote>\n<p>6.3.2.1 &#8211; 3: Except when it is the operand of the sizeof operator or the unary &amp; operator, or is a string literal used to initialize an array, an expression that has type \u2018\u2018array of type\u2019\u2019 is converted to an expression with type \u2018\u2018pointer to type\u2019\u2019 that points to the initial element of the array object and <strong>is not an lvalue<\/strong>. If the array object has register storage class, the behavior is undefined.<\/p>\n<\/blockquote>\n<p>So I think this is valid:<\/p>\n<pre><code>unsigned char *p = a[1]; \nunsigned char c = p[7]; \/\/ Strict aliasing not applied for char types\n<\/code><\/pre>\n<p>This is UB:<\/p>\n<pre><code>unsigned char c = a[1][7];\n<\/code><\/pre>\n<p>Because <code>a[1]<\/code> is not an lvalue at this point, but evaluated further, violating J.2 with an array subscript out of range. What really happens should depend on how the compiler actually implements the array indexing in multidimensional arrays. So you may be right that it doesn&#8217;t make any difference on every known implementation. But that&#8217;s a valid undefined behaviour, too. \ud83d\ude09<\/p>\n<p id=\"rop\"><small>Originally posted 2013-11-09 23:21:12. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>A compiler vendor who wants to write a conforming compiler is bound to what the Standard has to say, but not to your reasoning. The Standard says that an array subscript out of range is undefined behaviour, without any exception, so the compiler is allowed to blow up. To cite my comment from our last [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1070","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1070","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1070"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1070\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1070"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1070"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1070"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}