const-qualified pointers are largely useless. If a struct contains such a thing, it can't be dynamically allocated. As a function parameter, it doesn't protect the caller from anything because passing is by value.
Let's see how many times this occurs in my TXR project (~75K lines):
$ git grep -F '*const'
$ git grep -F '* const'
linenoise/linenoise.c: const wchar_t * const *lelem = convert(const wchar_t * const *, larg);
linenoise/linenoise.c: const wchar_t * const *relem = convert(const wchar_t * const *, rarg);
One place: a comparison function for a qsort call, where a vector of const wchar_t * strings is being sorted. I didn't write this (though I did convert it to wchar). qsort passes const void (star) pointers to the elements, which are const wchar_t (star), thus things end up like this.How about Linux kernel 4.9? There are numerous occurrences of this involving arrays declared at file scope, like this:
static const char *const foo[] = { "abc", "def" };
Let's filter those out to find other uses: # lines that start with at least one tab and contain *const,
# possibly with optional spaces between * and const:
kernel-4.9$ git grep '^[\t].*\*[ ]*const\>'
kernel-4.9$
Wow, not a single result!Let's relax that and allow a space or tab [\t ]. Then there are lots of false positives due to items in block commented lines starting with a ' asterisk' sequence. If we require at least one lower-case alpha character before star-const, we filter most of these out:
kernel-4.9$ git grep '^[\t ].*[a-z].*\*[ ]*const\>'
Documentation only, showing useless const parameters in a function prototype decl: Documentation/cpuidle/driver.txt: const struct cpumask *const coupled_cpus);
Documentation/media/kapi/v4l2-controls.rst: s32 skip_mask, s32 def, const char * const *qmenu);
False positive, in a table inside a block comment: arch/powerpc/xmon/ansidecl.h: PTRCONST `void *const' `char *'
Useless const parameter in function pointer signature. The definition of these operations are not required to use const: drivers/net/wan/lmc/lmc_var.h: void (* set_circuit_type)(lmc_softc_t * const, int);
drivers/net/wan/lmc/lmc_var.h: void (* watchdog)(lmc_softc_t * const);
Real result: drivers/of/fdt.c: const char *const *compat)
Real result: drivers/staging/vc04_services/interface/vchi/vchi.h: const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */
Fluff sibling: drivers/staging/vc04_services/interface/vchi/vchi.h: void * const bulk_handle );
Low-value const parameter in function definition: drivers/usb/mon/mon_text.c: char __user * const buf, const size_t nbytes)
Real result (Yacc/Bison skeleton origin): scripts/genksyms/parse.tab.c_shipped: YYSTYPE const * const yyvaluep;
scripts/genksyms/parse.tab.c_shipped: YYSTYPE const * const yyvaluep;
scripts/kconfig/zconf.tab.c_shipped: YYSTYPE const * const yyvaluep;
scripts/kconfig/zconf.tab.c_shipped: YYSTYPE const * const yyvaluep;
Useless const pointer arg in prototype: tools/lib/subcmd/parse-options.h: const char * const usagestr[], int flags);
That's it; a mere spec of dust relative to the LOC count in this tree, half of it useless.