Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Why does C allow structs to have a tag? Date: Sat, 12 Jun 2021 12:42:27 -0700 Organization: None to speak of Lines: 40 Message-ID: <87eed6zx7g.fsf@nosuchdomain.example.com> References: <20210609104104.187@kylheku.com> <20210609135620.66@kylheku.com> <87wnr0z0o8.fsf@nosuchdomain.example.com> <87mtrwyrk7.fsf@nosuchdomain.example.com> <7tRwI.23036$73h1.4209@fx10.ams4> <20210611160729.280@kylheku.com> <87wnr00y56.fsf@bsb.me.uk> <20210611171319.390@kylheku.com> <9I%wI.16462$yVI1.8123@fx07.ams4> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="b3dc605b3c3d09671336ab6840e77b5e"; logging-data="1223"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/SdKsoRk4EHvVm/cSaciB4" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:0LJD/PgwaNgcjQkuNGgGzNukScE= sha1:FTnW3SJw81TrOKwt+h+GaKhgSA0= Xref: csiph.com comp.lang.c:161410 Bart writes: [...] > Alternatively we can go with your idea of using a function pointer > type that cannot be called by accident: > > typedef void(*fnptr)(int,int,int,int,int,int); > > fnptr functable[]={(fnptr)printf, (fnptr)malloc, (fnptr)fwrite}; > > Except now gcc complains of casts between incompatible pointer > types. That gives me a warning only if I enable gcc's "-Wcast-function-type" option, which is included in "-Wextra". The code is valid (though as Kaz points out, you have to store some other information to be able to use the pointers safely). Compilers are allowed to warn about anything they like. > And it has a point. It needs to go through an intermediate > type: > > fnptr functable[]={(fnptr)(uintptr_t)printf, > (fnptr)(uintptr_t)malloc, (fnptr)(uintptr_t)fwrite}; No, you don't need to go through an intermediate type. The original code is safe and portable. Your version with the intermediate type is not (it would fail on an implementation where a function pointer can't be converted to uintptr_t without loss of information). You've made the code worse for the sake of avoiding a warning. Your void* approach was actually better than your uintptr_t approach (but still not 100% portable, but I know you don't care about that). [...] -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */