Menu ▾ ▴

#4138 Old-style (K&R) function definitions silently accept void parameters

open
nobody
None
Front-end
5
15 hours ago
15 hours ago
No

1: Sample code that reproduces the problem.

void f(value)
void value;
{
  (void)sizeof &value;
}

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

sdcc -mz80 --std=c89 -S repro.c

This is an old-style (K&R) function definition. --std=c89 selects a
language mode that permits that syntax; the same behaviour also reproduces
with --std=c11.

3: SDCC version tested.

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 #16997 (Linux)

4: Observed and expected behaviour.

SDCC exits successfully and emits no diagnostic on Z80, STM8 and MCS51 with --stack-auto. The parameter declaration gives value type void; it does not denote a function with no parameters, as f(void) would. The body asks only for the size of a pointer to the parameter, avoiding an unreferenced-parameter warning and SDCC's separate diagnostic when casting a void expression to void.

GCC 16.2.0 rejects the same source with:

error: parameter 'value' declared with void type

It would be useful for SDCC to diagnose the invalid parameter consistently, before target-dependent allocation. MCS51 default/large, PDK14 and S08 already reject the sample with error 66:

attempt to allocate variable of unknown size 'value'

C11 draft N1570,
6.9.1 paragraph 7, requires each adjusted parameter type in a function definition, including an identifier-list definition, to be a complete object type. void does not satisfy this requirement.

If the declarator includes an identifier list, the types of the parameters shall be declared in a following declaration list. In either case, the type of each parameter is adjusted as described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object type.

5: Additional checks and Compiler Explorer comparison.

Compiler Explorer: SDCC r16997 beside GCC 16.2.
Both panes use the sample above. SDCC uses -mz80 --std=c89; GCC uses -std=c89 -pedantic-errors -fsyntax-only. Compiler versions, compilation results, shared source and saved compiler options were checked on 12 October 2026. SDCC is silent; GCC diagnoses the void parameter.

A typedef alias for void behaves the same way. Old-style definitions with an int parameter or a void * parameter, and a definition using f(void), are valid cases: all three compile without diagnostics on all seven local configurations and are accepted by GCC 16.2 on Compiler Explorer.

Configuration Direct void parameter, C89 and C11 modes Typedef for void, C89 mode
Z80 Accepted silently Accepted silently
STM8 Accepted silently Accepted silently
MCS51 stack-auto Accepted silently Accepted silently
MCS51 default Error 66 Error 66
MCS51 large Error 66 Error 66
PDK14 Error 66 Error 66
S08 Error 66 Error 66

The current candidate for bugs:#4135 does not change these results. That candidate checks completeness in checkFunction, called by createFunctionDecl; old-style parameter declarations are merged afterwards by mergeKRDeclListIntoFuncDecl. The parser's existing void-parameter checks handle parameter-type lists, but do not catch this declaration-list form.

Discussion


Log in to post a comment.