Patch for new gnu compiler warning: deprecated conversion from string constant to 'char*'

Kevin Glynn kevin.glynn at gmail.com
Sun Apr 27 16:22:25 CEST 2008


Dear *,

If you compile mozart with an up to date GNU compiler you will get
lots of warnings like this:

/home/keving/debian/mozart/mozart-1.3.2.20060615+dfsg/mozart/contrib/os/io.cc:207: warning: deprecated conversion from string constant to 'char*'
 
This is a new warning that flags code that assigns a string constant,
which has type 'const char *', to a variable with type 'char *'.

An expression with type 'const char *' means that code is not allowed
to overwrite any part of the character string.

I haven't read the C++ standard, but I speculate that since string
constants have type 'const char *' they could be put in a read-only
area of the executable and the compiler could share separate
references to the same character string.

It is still allowed to cast a 'const char *' to a 'char *' but (again
speculation) the behaviour must be undefined if the program tries to
overwrite any part of that string. 

Possibly the above warning will eventually become an error, I don't
know, but at any rate it makes Mozart builds look very ugly and there
has already been a question about it on the users list.

I have made a patch (attached) for the Debian port of Mozart that
addresses this problem.  However, I don't use mozart regularly (boo!)
and I hardly program in C(++) these days (hurrah!) so I would like
someone else to take the patch and apply it to the Mozart repository.
It should apply easily to the mozart-1-3-0-fixes branch, and probably
to trunk too. (Although I generated it from Debian's debdiff tool you
might have to strip out those 
  only in patch2:
  unchanged:
lines).

I have mostly done things without applying much thought.  I would be
happy for any comments or improvements from you folks.

I have checked my diff for sanity and run the test suite (but not
dp. can someone run the distribution tests?)

cheers
k



** Details, Details

Unfortunately, the fix isn't as straightforward as we would like. For
uses internal to the emulator we just change variables declared 'char
*'to be 'const char *'. This has the same semantics and just adds more
compiler checking.  However, there are interfaces defined in mozart.h
and mozart_cpi.hh (I believe these are the only header files that
external native functors should compile against) that have declared
'char *' arguments that we pass string constants too.  If we change
them to be 'const char *' then pre-compiled functors will fail to link
to them (shame! why won't the linker allow something declared 'char *'
to link to something declared 'const char *'?).

These interfaces should be fixed next time we make an API-changing
release of Mozart, but we can't break them for Mozart 1.3.2.  Here are
those interfaces and what I did to work around this:

*** mozart.h

 _FUNDECL(OZ_Term  ,OZ_mkTupleC,(char *label,int arity,...));
+_FUNDECL(OZ_Term  ,OZ__mkTupleCConstLabel,(const char *label,int
arity,...));
 
Added new OZ__mkTupleCConstLabel function, a copy of OZ__mkTupleC with
const char* label.

 _FUNDECL(OZ_Return ,OZ_typeError,(int pos,char *type));
+#define OZ__typeErrorConstType(pos,type)            \
+  OZ_typeError(pos,(char *)type)
+

Added new macro OZ__typeErrorConstType that casts type to a (char
*). Note that OZ_typeError just calls oz_typeError that does have type
declared 'const char *'!


 _FUNDECL(OZ_Return ,OZ_raiseC,(char *label,int arity,...));
+_FUNDECL(OZ_Return ,OZ__raiseCConstLabel,(const char *label,int
arity,...));
+
+
 _FUNDECL(OZ_Return ,OZ_raiseErrorC,(char *label,int arity,...));
+_FUNDECL(OZ_Return ,OZ__raiseErrorCConstLabel,(const char *label,int arity,...));
+
 _FUNDECL(OZ_Term   ,OZ_makeException,(OZ_Term kind,OZ_Term  key,char*label,int arity,...));
+_FUNDECL(OZ_Term   ,OZ__makeExceptionConstLabel,(OZ_Term kind,OZ_Term key,const char*label,int arity,...));

Added new OZ__XXXXXConstLabel function, a copy of OZ__XXXXX with const
char* label.

 #define OZ_expectType(ARG,MSG,CHECK)           \
 OZ_expectDet(ARG);
 \
 if (!CHECK(OZ_in(ARG))) {                      \
-  return OZ_typeError(ARG,MSG);                                \
+  return OZ_typeError(ARG,(char *)MSG);         \
 }
 
 #define OZ_expectRecType(ARG,MSG,CHECK)                \
 {
 \
   OZ_Term OZ__aux__;                           \
   if (!CHECK(OZ_in(ARG),&OZ__aux__)) {                 \
     if (OZ__aux__ == 0) {                                      \
-      return OZ_typeError(ARG,MSG);    \
+      return OZ_typeError(ARG,(char *)MSG);     \
     } else {                                                   \
       OZ_suspendOn(OZ__aux__);
       \
     }                                  \
 
Added (char *) casts to calls to OZ_typeError.

*** mozart_cpi.hh

-#define OZ_EXPECTED_TYPE(S) char * expectedType = S
+// Debian: S is often a string constant. Avoid gcc warnings by adding safe cast
+#define OZ_EXPECTED_TYPE(S) char * expectedType = (char *)S
 

+// Debian: Added a more specific version for comment="" and const typeString
+// allows to remove some warnings and not change previous (public) signature 
+_FUNDECL(OZ_Return,OZ_typeErrorCPI,(const char *, int));
 
 
+// Debian: Add macro for internal use that adds safe casts
+#define OZ__initPropagatorName(prop_member,name) \
+  prop_member = (char *)name
+

In many cases we assign a profile to a propagator like this (cute):

   OZ_PropagatorProfile WidthPropagator::profile = "BIwidthC";

but the proop_member is declared 'char *', so I added the macro
OZ__initPropagatorName which adds a cast and changed these assignments
to look like (not so cute):

   OZ_PropagatorProfile OZ__initPropagatorName(WidthPropagator::profile,"BIwidthC");

 
+// Debian: Add macro for internal use that adds safe casts
+#define OZ__typeErrorCPIConstComment(typeStr,pos,comment) \
+  OZ_typeErrorCPI((char *)typeStr,pos,(char *)comment)


*** platform/wish/unixMain.cc

I cast string constants to (char *), I believe this code is just
copied from elsewhere, so maybe there is an update for this.


*** parser.cc/scanner.cc

I didn't try to regenerate these to see if the warnings would go away,
so I just modified these files directly.  If you do try to regenerate
you should fix the calls to OZ_raiseErrorC etc. in parser.yy


And the patch:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: fixwarns.diff
Type: application/octet-stream
Size: 111421 bytes
Desc: Debian patch to address gnu compiler warnings
Url : http://lists.gforge.info.ucl.ac.be/pipermail/mozart-hackers/attachments/20080427/440708e0/fixwarns-0001.obj


More information about the mozart-hackers mailing list