Menu

#3963 Parameter is not taken as having the unqualified version of its declared type in assignment or initialisation

open
nobody
None
Front-end
5
2026-03-26
2026-03-26
No

1: Sample code that reproduces the problem.

int f1(const int);
int main(void)
{
    int (*fp1)(int) = f1;
    fp1 = f1;
    return 0;
}

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

sdcc -c --std=c23

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

SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8 TD- 4.5.0 #15242 (Linux)

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

<source>:4: error 78: incompatible types
from type 'int function ( const-int fixed) fixed'
  to type 'int function ( int fixed) fixed'
<source>:5: error 78: incompatible types
from type 'int function ( const-int fixed) fixed'
  to type 'int function ( int fixed) fixed'

I believe this is incorrect because the C23 standard says (6.5.17.2 "Simple assignment"):

the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left operand has all the qualifiers of the type pointed to by the right operand;

and (6.7.7.4 "Function declarators"):

In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.

See https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf

Based on the behaviour of GCC 15.2.0, Clang 22.1.0 and TCC 0.9.27, "the type pointed to by the left operand has all the qualifiers of the type pointed to by the right operand" isn't usually interpreted as applying to parameter types of the type pointed to by the left operand (or, recursively, parameter types of a type pointed to by a type pointed to by the left operand).

Discussion

  • Benedikt Freisen

    Can you retry with sdcc -c --std=c23 --stack-auto or sdcc -c --std=c23 -mz80?

    The observed behavior can potentially be explained with SDCC's default settings:

    For historical reasons, the default target -mmcs51 generates non-reeantrant function code, unless --stack-auto is specified. It then compares qualified function types, because it must not ignore (explicit or implicit) address space qualifiers. See also [feature-requests:#948], which addresses this unintuitiveness.

     

    Related

    Feature Requests: #948

  • Christopher Bazley

    Can you retry with sdcc -c --std=c23 --stack-auto or sdcc -c --std=c23 -mz80?

    No problem. I see no error messages with either of the configurations that you suggested: https://godbolt.org/z/3xsd3e7xo

    I expected that the answer might be something to do with address space qualifiers. Does that need to affect treatment of standard qualifiers though (or new qualifiers that have similar semantics to the standard qualifiers, like _Optional)?

     

Log in to post a comment.

MongoDB Logo MongoDB