Bug 20767

Summary: gcc const produces invalid warning
Product: Base System Reporter: marka <marka>
Component: gnuAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.1-STABLE   
Hardware: Any   
OS: Any   

Description marka 2000-08-22 04:10:00 UTC
	gcc incorrectly reports 'incompatible pointer type' when function
	is declared with 'const pointer to const pointer' arguement and is
	just passed pointer to pointer.

	Also generates error with 'const pointer to pointer' and 'pointer to
	const pointer', i.e. removing either of the consts still generates
	the warning.

How-To-Repeat: 
% cc xx.c
xx.c: In function `main':
xx.c:22: warning: passing arg 1 of `f' from incompatible pointer type

#include <stdio.h>

static const char *foo[] = { "test", NULL };

static int
f(const char * const *args) {
	int i, j, k;

	k = 0;
	for  (i = 0; args[i] != NULL; i++)
		for (j = 0; args[i][j] != '\0'; j++)
			k += args[i][j];
	return (k);
}

int
main(int argc, char **argv) {
	int i;
	
	i = f(foo);
	printf("%d\n", i); 
	i = f(argv);		/* This should not generate a warning! */
	printf("%d\n", i); 
	return (0);
}
Comment 1 Garrett A. Wollman 2000-08-22 04:15:43 UTC
<<On Tue, 22 Aug 2000 13:03:35 +1000 (EST), marka@nominum.com said:

> 	gcc incorrectly reports 'incompatible pointer type' when function
> 	is declared with 'const pointer to const pointer' arguement and is
> 	just passed pointer to pointer.

The code is in error, and the warning is in fact correct.  The type
`const foo * const *' is not compatible with `foo **'.  Only the
outermost qualifier participates in this form of promotion.

-GAWollman
Comment 2 Philip M. Gollucci 2000-08-22 04:24:15 UTC
Acutally shouldn't it.... 
Don't you want *argv ? as just argv implies the array of command line
arguments instead of any single character string !

I could be wrong, if you do use the * it works fine with no warning and
-Wall option as well.

*****************************************************************************
Philip M. Gollucci (p6m7g8)
Web-site    : http://www.p6m7g8.com
E-mail      : gollucci@wam.umd.edu 
	      Philip@p6m7g8.com 
Phone       : 301.249.6261 (Home)
	      301.   .	   (College)
Major       : Computer Science 
	      Electrical Engineering 
Minor	    : Classical & Jazz Performance
Current Job : Co Science, Discovery, & the Universe Webmaster
	      URL: http://www.sdu.umd.edu 
Resume	    : http://www.wam.umd.edu/~gollucci/resume.html
*****************************************************************************


On Tue, 22 Aug 2000 marka@nominum.com wrote:

> 
> >Number:         20767
> >Category:       gnu
> >Synopsis:       gcc const produces invalid warning
> >Confidential:   no
> >Severity:       non-critical
> >Priority:       medium
> >Responsible:    freebsd-bugs
> >State:          open
> >Quarter:        
> >Keywords:       
> >Date-Required:
> >Class:          sw-bug
> >Submitter-Id:   current-users
> >Arrival-Date:   Mon Aug 21 20:10:00 PDT 2000
> >Closed-Date:
> >Last-Modified:
> >Originator:     Mark Andrews
> >Release:        FreeBSD 4.1-STABLE i386
> >Organization:
> Nominum
> >Environment:
> 
> FreeBSD drugs.dv.isc.org 4.1-STABLE FreeBSD 4.1-STABLE #0: Fri Aug 18 13:53:08 EST 2000     marka@drugs.dv.isc.org:/usr/obj/usr/src/sys/DRUGS  i386
> 
> Using builtin specs.
> gcc version 2.95.2 19991024 (release)
> 
> >Description:
> 
> 	gcc incorrectly reports 'incompatible pointer type' when function
> 	is declared with 'const pointer to const pointer' arguement and is
> 	just passed pointer to pointer.
> 
> 	Also generates error with 'const pointer to pointer' and 'pointer to
> 	const pointer', i.e. removing either of the consts still generates
> 	the warning.
> 
> >How-To-Repeat:
> 
> % cc xx.c
> xx.c: In function `main':
> xx.c:22: warning: passing arg 1 of `f' from incompatible pointer type
> 
> #include <stdio.h>
> 
> static const char *foo[] = { "test", NULL };
> 
> static int
> f(const char * const *args) {
> 	int i, j, k;
> 
> 	k = 0;
> 	for  (i = 0; args[i] != NULL; i++)
> 		for (j = 0; args[i][j] != '\0'; j++)
> 			k += args[i][j];
> 	return (k);
> }
> 
> int
> main(int argc, char **argv) {
> 	int i;
> 	
> 	i = f(foo);
> 	printf("%d\n", i); 
> 	i = f(argv);		/* This should not generate a warning! */
> 	printf("%d\n", i); 
> 	return (0);
> }
> 
> >Fix:
> 
> 
> 
> >Release-Note:
> >Audit-Trail:
> >Unformatted:
> 
> 
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-bugs" in the body of the message
>
Comment 3 mark.andrews 2000-08-22 06:03:17 UTC
> Acutally shouldn't it.... 
> Don't you want *argv ?

	No.  Remove all the consts and it is clearer.
	e.g. f(char **args);

> as just argv implies the array of command line
> arguments instead of any single character string !
> 
> I could be wrong, if you do use the * it works fine with no warning and
> -Wall option as well.
> 
--
Mark Andrews, Nominum Inc.
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: Mark.Andrews@nominum.com
Comment 4 mark.andrews 2000-08-22 06:20:14 UTC
> <<On Tue, 22 Aug 2000 13:03:35 +1000 (EST), marka@nominum.com said:
> 
> > 	gcc incorrectly reports 'incompatible pointer type' when function
> > 	is declared with 'const pointer to const pointer' arguement and is
> > 	just passed pointer to pointer.
> 
> The code is in error, and the warning is in fact correct.  The type
> `const foo * const *' is not compatible with `foo **'.  Only the
> outermost qualifier participates in this form of promotion.
> 
> -GAWollman
> 
	If that is what ANSI C says I'll have to live with it but it is
	illogical, not that logic applies to standards.
	
	Mark
--
Mark Andrews, Nominum Inc.
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: Mark.Andrews@nominum.com
Comment 5 Sheldon Hearn freebsd_committer freebsd_triage 2000-08-22 15:46:37 UTC
State Changed
From-To: open->closed

Garrett reckons that gcc is conformant in this regard.