From owner-freebsd-arch@FreeBSD.ORG Mon May 29 11:10:20 2006 Return-Path: X-Original-To: freebsd-arch@freebsd.org Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1DB3316A435 for ; Mon, 29 May 2006 11:10:00 +0000 (UTC) (envelope-from bde@zeta.org.au) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id ABF4943D48 for ; Mon, 29 May 2006 11:09:59 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy1.pacific.net.au (mailproxy1.pacific.net.au [61.8.0.86]) by mailout1.pacific.net.au (Postfix) with ESMTP id 8FAB63A7F81; Mon, 29 May 2006 21:09:58 +1000 (EST) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailproxy1.pacific.net.au (8.13.4/8.13.4/Debian-3sarge1) with ESMTP id k4TB9tJK027874; Mon, 29 May 2006 21:09:56 +1000 Date: Mon, 29 May 2006 21:09:55 +1000 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Yar Tikhiy In-Reply-To: <20060528164328.GA84031@comp.chem.msu.su> Message-ID: <20060529200215.T24032@delplex.bde.org> References: <20060528164328.GA84031@comp.chem.msu.su> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-arch@freebsd.org Subject: Re: Can fts_open() be constified further? X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 May 2006 11:10:20 -0000 On Sun, 28 May 2006, Yar Tikhiy wrote: > Currently, fts_open() is declared as follows: > > FTS * > fts_open(char * const *path_argv, int options, > int (*compar)(const FTSENT * const *, const FTSENT * const *)); > > This means that one cannot pass pointers to constant strings in > path_argv[] without getting rather justified warnings from cc. > AFAIK, fts(3) functions aren't supposed to modify the path strings. > Hence the prototype asks to be changed slightly: > > fts_open(const char * const *path_argv, int options, > ^^^^^ > This shouldn't break fts consumers because a pointer to a variable > can be converted to a pointer to a constant w/o warnings (but not > the other way around.) Can anybody see other possible side effects > from such change? It wouldn't work, for the same reasons that it doesn't work for execve(): plain "char **" cannot be converted to "const char * const *". Only "const char **" and of course itself can be converted. "char * const *" cannot be converted but is weird compared with "char **". All this follows from the type rule that you expressed informally. "const" can only be added at the outer level when the inner types are the same. Set T1 = "char *" and T2 = "const char *" to reduce confusion about the levels. Then: char ** = pointer to T1 = PT1 char * const * = const pointer to T1 = CPT1 const char ** = pointer to T2 = PT2 const char * const * = const pointer to T2 = CPT2 PT1 can be converted to CPT1 and PT2 can be converted to CPT2. No other conversions from adding a "const" are permitted, since T1 != T2. The prototypes for the execve() family and presumably for fts_open() are chosen so that the most important non-constified type (PT1) can be converted to the type in the prototype (CPT1). PT1 cannot be converted to CPT2 since "const" is not very well designed. Allowing this conversion without redesigning "const" would make "const" even less well designed. From the draft C standard (n869.txt): %%% [#6] EXAMPLE 3 Consider the fragment: const char **cpp; char *p; const char c = 'A'; cpp = &p; // constraint violation *cpp = &c; // valid *p = 0; // valid The first assignment is unsafe because it would allow the following valid code to attempt to change the value of the const object c. %%% It looks harmless to add a "const" to the inner type in &p, but this example shows that it unsafe. Bruce