On Thu, Jun 30, 2005 at 09:33:50AM +0100, Steve Hay wrote:
> Yitzchak Scott-Thoennes wrote:
> 
> >On Mon, Jun 27, 2005 at 10:46:19AM +0100, Steve Hay wrote:
> >  
> >
> >>win32/win32.c currently generates warnings under gcc.  The problem is 
> >>reproduced by:
> >>
> >>#include <process.h>
> >>int main() {
> >>    const char *cmdname;
> >>    const char *const *argv;
> >>    return execv(cmdname, (char *const *)argv);
> >>}
> >>
> >>which causes gcc to complain:
> >>
> >>test.c:5: warning: passing arg 2 of `execv' from incompatible pointer type
> >>
> >>In MinGW (and VC++) execv's 2nd arg is const char *const *, so simply 
> >>removing the cast makes it happy.  However, in Borland C execv's 2nd arg 
> >>is just char * const * (hence the reason for the cast in the first place 
> >>-- must have been written by a Borland C user!), so removing the cast 
> >>makes bcc32 complain:
> >>
> >>Warning W8075 test.c 5: Suspicious pointer conversion in function main
> >>
> >>How can I keep both compilers (gcc and bcc32) happy?  Is #ifdef hell the 
> >>only way, e.g.
> >>
> >>#ifdef __BORLANDC__
> >>    return execv(cmdname, (char *const *)argv);
> >>#else
> >>    return execv(cmdname, argv);
> >>#endif
> >>
> >>Why does gcc complain in the first place, though?  I thought that 
> >>passing a non const arg to a function with a const parameter was 
> >>generally not a problem, and indeed, VC++ didn't complain.  What is 
> >>gcc's problem?
> >>    
> >>
> >
> >There's discussion of this (that I didn't understand, but maybe you
> >will) in the SUSv3 execv page, under Rationale, that implies that gcc
> >is technically correct in having a problem.  If you have to resort to
> >ifdef hell, I'd make it check for mingw, not for __BORLANDC__, since
> >mingw is what's getting the prototype wrong.
> >
> I didn't understand it either, and I don't understand your conclusion 
> that it implies gcc has a problem.  Why did you think it implies that?

It says "due to a limitation of ISO C...specifying two levels of
const-qualification...would disallow existing correct code"
(presumably constless code).  And the table shows that assigning
a "const char * const []" to a "char * const []" is not valid.
So I'm saying that implies gcc is correct in giving the warning.
 
> Are you suggesting that I should write
> 
> #ifdef __MINGW__
>     return execv(cmdname, argv);
> #else
>     return execv(cmdname, (char *const *)argv);
> #endif
> 
> ?  I can't see that that is an improvement because it now applies the 
> cast in the VC++ case too, which doesn't need a cast since it has the 
> correct prototype to start with.

I thought from what you said that it doesn't warn, so it wouldn't hurt
to pass the args correctly.
 
> The way I saw it is that it is Borland that gets the prototype wrong and 
> hence Borland that needs the cast.

Borland has:

int  _RTLENTRY _EXPFUNC execv(const char * __path, char * const * __argv);

VC+:

_CRTIMP int __cdecl execv(const char *, const char * const *);

MinGW:

_CRTIMP int __cdecl _execv (const char*, const char* const*);

SUSv3 (http://www.opengroup.org/onlinepubs/009695399/functions/execv.html):

int execv(const char *path, char *const argv[]);


So Borland is the only one of the three that gets it right.

Reply via email to