Comment

Comment by kazinator

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.
parent kazinator 7 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton