Opened 7 years ago
Closed 7 years ago
#6602 closed defect (fixed)
C does not like const of CSLFindString as done in r34749
Reported by: | Kurt Schwehr | Owned by: | Kurt Schwehr |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | default | Version: | svn-trunk |
Severity: | blocker | Keywords: | |
Cc: |
Description (last modified by )
e.g. https://travis-ci.org/rouault/gdal_coverage/builds/146409340
gcc -I/home/travis/build/rouault/gdal_coverage/gdal/port -I/home/travis/build/rouault/gdal_coverage/gdal/gcore -I/home/travis/build/rouault/gdal_coverage/gdal/alg -I/home/travis/build/rouault/gdal_coverage/gdal/ogr -I/home/travis/build/rouault/gdal_coverage/gdal/ogr/ogrsf_frmts -I/home/travis/build/rouault/gdal_coverage/gdal/gnm -I/home/travis/build/rouault/gdal_coverage/gdal/apps -fPIC -g -DDEBUG -ftrapv -Wall -Wdeclaration-after-statement -Wextra -Winit-self -Wunused-parameter -Wmissing-prototypes -Wmissing-declarations -Wformat -Werror=format-security -Wno-format-nonliteral -Wlogical-op -Wshadow -Werror=vla -Wdeclaration-after-statement -DDEBUG_BOOL -Wextra -Werror -I../shape -I.. -I../.. -DOGR_ENABLED -D_REENTRANT -I/home/travis/build/rouault/gdal_coverage/gdal/port -I/usr/local/include -I/usr/include -DGDAL_COMPILATION -c -o ../o/avc_e00read.o avc_e00read.c avc_e00read.c: In function ‘_AVCE00ReadBuildSqueleton’: avc_e00read.c:1040:5: error: passing argument 1 of ‘CSLFindString’ from incompatible pointer type [-Werror] /home/travis/build/rouault/gdal_coverage/gdal/port/cpl_string.h:106:13: note: expected ‘const char * const*’ but argument is of type ‘char **’ avc_e00read.c:1061:5: error: passing argument 1 of ‘CSLFindString’ from incompatible pointer type [-Werror] /home/travis/build/rouault/gdal_coverage/gdal/port/cpl_string.h:106:13: note: expected ‘const char * const*’ but argument is of type ‘char **’ ... cc1: all warnings being treated as errors
What exactly is this complaining about?
Possible solutions (will they even work)?
- Separate out a new const function and have the old call the new. CSLFindStringConst or CSLFindString2 or CSLFindStringEx
- Provide a different signature for C without the const (if it will link)
- Have a define like GDAL_CONST_STRICT to provide a more cost API for places that want it
- Revert and give up in despair
- Can we cast in the C code?
- Convert C code to C++ (doesn't help mapserver, which is C)
- Or?
Reported by EvenR.
Example code that is failing (from Ubuntu 14.04 @ r34748):
/* avc_e00read.c */ static int _AVCE00ReadBuildSqueleton(AVCE00ReadPtr psInfo, char **papszCoverDir) { /* ... */ szFname = (psInfo->eCoverType==AVCCoverV7 || psInfo->eCoverType==AVCCoverPC2 ) ? "arc.adf": "arc"; if ( (iFile=CSLFindString(papszCoverDir, szFname)) != -1 && (psFile = AVCBinReadOpen(psInfo->pszCoverPath, szFname, psInfo->eCoverType, AVCFileARC, psInfo->psDBCSInfo)) != NULL) {
Fails like:
avc_e00read.c: In function '_AVCE00ReadBuildSqueleton': avc_e00read.c:1040:5: warning: passing argument 1 of 'CSLFindString' from incompatible pointer type [enabled by default] if ( (iFile=CSLFindString(papszCoverDir, szFname)) != -1 && ^ In file included from avc.h:119:0, from avc_e00read.c:129: /home/schwehr/src/gdal/gdal/port/cpl_string.h:106:13: note: expected 'const char * const*' but argument is of type 'char **' int CPL_DLL CSLFindString( const char * const *, const char * );
Could cast in C:
szFname = (psInfo->eCoverType==AVCCoverV7 || psInfo->eCoverType==AVCCoverPC2 ) ? "arc.adf": "arc"; if ( (iFile=CSLFindString((const char * const *)papszCoverDir, szFname)) != -1 && (psFile = AVCBinReadOpen(psInfo->pszCoverPath, szFname, psInfo->eCoverType, AVCFileARC, psInfo->psDBCSInfo)) != NULL) {
Or modify cpl_string.h to present non-const to C. (least bad so far)
#ifdef __cplusplus int CPL_DLL CSLFindString( const char * const *, const char * ); int CPL_DLL CSLFindStringCaseSensitive( const char * const *, const char * ); int CPL_DLL CSLPartialFindString( const char * const *papszHaystack, const char * pszNeedle ); #else // Present non-const to C code that does not like passing non-const to const. int CPL_DLL CSLFindString( char **, const char * ); int CPL_DLL CSLFindStringCaseSensitive( char **, const char * ); int CPL_DLL CSLPartialFindString( char **papszHaystack, const char * pszNeedle ); #endif
Change History (3)
comment:1 by , 7 years ago
Description: | modified (diff) |
---|
comment:2 by , 7 years ago
Description: | modified (diff) |
---|---|
Status: | new → assigned |
comment:3 by , 7 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
r34750 Marking as fixed. Reopen if this doesn't work somehow.
Apparently the general reason for this restriction is that if you could pass "char " into "const char ", then you could assign a "const char *" to the outer pointer and thus allow the caller to violate constness. C++ has a more complex rule which recognizes that "const char * const *" is safe against this, but C does not.