This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: inconsistent 'const' in exec{l,v}.


On Friday 18 of November 2011 00:41:17 Carlos O'Donell wrote:
> 2011/11/17 Mark Brown <bmark@us.ibm.com>:
> >> i've noticed that manual describes variable number of 'const char*'
> >> arguments for execl()
> >> and array of non-const arguments for execv(). is it a bug or an
> >> intelligent design?
> >> imho it should be declared as 'const char* const argv[]'.
> >
> > I'll refer you to the POSIX spec (online at
> > http://pubs.opengroup.org/onlinepubs/9699919799/nframe.html ) for
> > how the exec* functions are specified.
> 
> C has no notion of "constant data" just that "the contents pointed to
> by the pointer won't change" and "the location pointed to by this
> pointer won't change" (See 6.7.5.1.3 in ISO C99).
> 
> Therefore the POSIX standard, as explained in the Open Group
> description, has to choose the best option keeping in mind existing
> code.
> 
> Specifying the function using "const char* const argv[]" as you
> suggest would break existing code by requiring a cast and still
> doesn't specify exactly what is intended by the interface and which
> can't be expressed in C anyway.

thanks for the explanation. my confusion came from such reduced c++ code:

$ cat args.cpp

#include <string>
#include <vector>
#include <unistd.h>
void run( std::string const& executable, std::vector< std::string > const& args )
{
        char const* argv[ args.size() + 1 ];
        unsigned index( 0 );
        for ( std::vector< std::string >::const_iterator i = args.begin(); i != args.end(); ++i )
                argv[ index++ ] = i->c_str();
        argv[ index ] = 0;
        ::execvp( executable.c_str(), argv );     // <== c++ compilation error.
}

$ LANG=C g++ -Wall args.cpp -c
args.cpp: In function 'void run(const string&, const std::vector<std::basic_string<char> >&)':
args.cpp:11:37: error: invalid conversion from 'const char**' to 'char* const*' [-fpermissive]
/usr/include/unistd.h:575:12: error:   initializing argument 2 of 'int execvp(const char*, char* const*)' [-fpermissive]

finally, i've ended with const_cast<> to satisfy execvp() interface and strict c++ diagnostics:

void run( std::string const& executable, std::vector< std::string > const& args )
{
        char* argv[ args.size() + 1 ];
        unsigned index( 0 );
        for ( std::vector< std::string >::const_iterator i = args.begin(); i != args.end(); ++i )
                argv[ index++ ] = const_cast< char* >( i->c_str() );
        argv[ index ] = 0;
        ::execvp( executable.c_str(), argv );
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]