Menu ▾ ▴

#4164 Qualifying an array typedef qualifies pointer targets instead of pointer elements

open
nobody
None
Front-end
5
2026-10-20
2026-10-20
No

1: Sample code that reproduces the problem.

typedef int *Row[3];
typedef int *const ConstRow[3];

void direct(int *const (*p)[3])
{
  _Static_assert(_Generic(p, ConstRow *: 1, default: 0),
                 "direct declaration");
}

void alias(const Row *p)
{
  _Static_assert(_Generic(p, ConstRow *: 1, default: 0),
                 "qualified array typedef");
}

Compiler Explorer: SDCC, GCC 16.2 and Clang 19.1.

2: Exact command used to run SDCC on this sample code.

sdcc -mz80 --std-c23 -S qualified-array-typedef.c

3: SDCC version tested (type "sdcc -v" to find it).

SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/huc6280/f8/f8l TD- 4.6.4 #17013 (Linux)
published under GNU General Public License (GPL)

Compiler Explorer's SDCC trunk compiler, checked 20 October 2026. The
reported revision is r17013.

4: Copy of the error message or incorrect output, or a clear description of the observed versus expected behaviour.

<source>:12: warning 215: static assertion failed: "qualified array typedef"

Both assertions should pass. Row is an array of three pointers to int. Qualifying that array type with const qualifies its pointer elements, so const Row and ConstRow should denote the same type. Both parameters should therefore have type pointer to an array of three const pointers to int. SDCC instead appears to apply the qualifier to the pointed-to int.

Adding this typedef and using WrongRow * as the association type in the second assertion makes that assertion pass:

typedef const int *WrongRow[3];

5: Additional checks.

GCC 16.2 and Clang 19.1.0 accept the original sample without diagnostics with -std=c23 -pedantic-errors -Wall -Wextra, as shown in the linked CE example.

Replacing const with _Optional in the two qualified type declarations also makes SDCC fail the second assertion. This was discovered while checking [bugs:#4162], but the sample above contains neither _Optional nor unary &.

Related

Bugs: #4162
Bugs: #4165

Discussion

  • Christopher Bazley

    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -41,8 +41,7 @@
     &lt;source&gt;:12: warning 215: static assertion failed: &#34;qualified array typedef&#34;
     ```
    
    -Both assertions should pass. `Row` is an array of three pointers to `int`. Qualifying that array type with `const` qualifies its pointer elements, so `const Row` and `ConstRow` should denote the same type. Both parameters should therefore have type pointer to an array of three const pointers to
    -`int`. SDCC instead appears to apply the qualifier to the pointed-to `int`. 
    +Both assertions should pass. `Row` is an array of three pointers to `int`. Qualifying that array type with `const` qualifies its pointer elements, so `const Row` and `ConstRow` should denote the same type. Both parameters should therefore have type pointer to an array of three const pointers to `int`. SDCC instead appears to apply the qualifier to the pointed-to `int`. 
    
     Adding this typedef and using `WrongRow *` as the association type in the second assertion makes that assertion pass:
     ```c
    
     
  • Christopher Bazley

    Attaching a candidate fix for this patch, created in discussion/argument with Codex.

     

Log in to post a comment.