The typedef of function without pointer should be allowed as well as following use of function type with pointer symbol to declare pointer to the function variable or structure fields. Such use is directly mandated by examples in C99 standard
/* C99 6.7.7 Type definitions 7 EXAMPLE 4 */ typedef void fv(int), (*pfv)(int); void (*signal(int, void (*)(int)))(int); fv *signal(int, fv *); pfv signal(int, pfv); */
But SDCC report some of these contructs as error after #2440 resolution
/* Following should be supported to not block reuse/porting of code */ typedef long fnc_t(int a, long b); /* but SDCC reports test-func-typedef.c:11: error 220: type 'fnc_t' is function */ typedef long (*fnc_p_t)(int a, long b); /* This seems to be supported by compilers but not sure if required by standard */ fnc_t fnc1, fnc2; long fnc1(int a, long b) { return 0; } fnc_t *fncp = &fnc1; long test(void) { long l = fncp(1, 2); fnc_p_t fp = fncp; return fp(l, 0); }
Next are not necessarily correct and reporting them as error can help catch errors made by programmers even that some constructs are GCC accepted.
/* fnc_t fncp1 = &fnc1; error: function 'fncp1' is initialized like a variable */ /* fnc_t *fncp2 = fnc1; OK for GCC but not sure if according to C99 standard */
Same as original reported construct is error and should be reported.
typedef void test_func_t(void); static test_func_t test_funcs[1]; /* error: declaration of 'test_funcs' as array of functions */
But reporting as errors C99 valid constructs requires to adjust portable code specially for SDCC use and causes code less readable in some cases. It can be unacceptable for upstream projects and instead of accepting change it may be easier to drop SDCC support.
Please, consider to change parser to accept standard specified constructs.
My opinion,
(1) The following a.c should be accepted,
~
(2) The following c.c should be accepted,
~
(3) The following e.c should be rejected,
~
(4) The following f.c should be rejected,
~
(5) The following g.c should be accepted,
Last edit: Ben Shi 2016-04-25
I fully agree with that.
fnc_t fnc1; is seldom used so it is not so big problem if it is not accepted. But others are quite common.
Fixed in [r9580].
Last edit: Maarten Brock 2017-05-13
Hi Ben,
Condition 1 'a.c' does not work in version 3.6.6. I get error 220, see my comment below. Please reopen this bug
Last edit: Maarten Brock 2017-05-13
Hi,
I use condition (1) 'a.c' to typedef module callback functions which are then used to declare a static function in main code but it no longer works even with the latest build 3.6.3 #9761. Unlike Pavel I think this feature is important and makes code easier to read and maintain
ie.
in module header:
typedef void io_hardware_callback_t(io_hardware_event_t, unsigned short);
in main code:
// this used to work in 3.4.0 but not now >>> static io_hardware_callback_t hardware_callback;
static void hardware_callback(io_hardware_event_t, unsigned short);
uncommenting the above results in
error 220: 'hardware_callback' has function type
cheers Brad