Skip to content

Commit 6c24b84

Browse files
committed
Warn on implicit conversions
Behavior can be turned off by defining RCPP_DONT_WARN_ON_COERCE.
1 parent 373a8b4 commit 6c24b84

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

inst/include/Rcpp/r_cast.h

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
namespace Rcpp{
2828
namespace internal {
29-
29+
3030
inline SEXP convert_using_rfunction(SEXP x, const char* const fun){
3131
Armor<SEXP> res ;
3232
try{
@@ -37,15 +37,15 @@ namespace Rcpp{
3737
}
3838
return res;
3939
}
40-
40+
4141
// r_true_cast is only meant to be used when the target SEXP type
42-
// is different from the SEXP type of x
42+
// is different from the SEXP type of x
4343
template <int TARGET>
4444
SEXP r_true_cast( SEXP x) {
4545
throw not_compatible( "not compatible" ) ;
4646
return x ; // makes solaris happy
4747
}
48-
48+
4949
template <int RTYPE>
5050
SEXP basic_cast( SEXP x){
5151
if( TYPEOF(x) == RTYPE ) return x ;
@@ -62,28 +62,28 @@ namespace Rcpp{
6262
return R_NilValue ; /* -Wall */
6363
}
6464

65-
template<>
65+
template<>
6666
inline SEXP r_true_cast<INTSXP>(SEXP x){
67-
return basic_cast<INTSXP>(x) ;
67+
return basic_cast<INTSXP>(x) ;
6868
}
69-
template<>
69+
template<>
7070
inline SEXP r_true_cast<REALSXP>(SEXP x){
71-
return basic_cast<REALSXP>(x) ;
71+
return basic_cast<REALSXP>(x) ;
7272
}
73-
template<>
73+
template<>
7474
inline SEXP r_true_cast<RAWSXP>(SEXP x){
75-
return basic_cast<RAWSXP>(x) ;
75+
return basic_cast<RAWSXP>(x) ;
7676
}
77-
template<>
77+
template<>
7878
inline SEXP r_true_cast<CPLXSXP>(SEXP x){
7979
return basic_cast<CPLXSXP>(x) ;
8080
}
81-
template<>
81+
template<>
8282
inline SEXP r_true_cast<LGLSXP>(SEXP x){
8383
return basic_cast<LGLSXP>(x) ;
8484
}
85-
86-
template <>
85+
86+
template <>
8787
inline SEXP r_true_cast<STRSXP>(SEXP x){
8888
switch( TYPEOF( x ) ){
8989
case CPLXSXP:
@@ -101,42 +101,55 @@ namespace Rcpp{
101101
case CHARSXP:
102102
return Rf_ScalarString( x ) ;
103103
case SYMSXP:
104-
return Rf_ScalarString( PRINTNAME( x ) ) ;
104+
return Rf_ScalarString( PRINTNAME( x ) ) ;
105105
default:
106106
throw ::Rcpp::not_compatible( "not compatible with STRSXP" ) ;
107107
}
108108
return R_NilValue ; /* -Wall */
109109
}
110-
template<>
110+
template<>
111111
inline SEXP r_true_cast<VECSXP>(SEXP x) {
112-
return convert_using_rfunction(x, "as.list" ) ;
112+
return convert_using_rfunction(x, "as.list" ) ;
113113
}
114-
template<>
114+
template<>
115115
inline SEXP r_true_cast<EXPRSXP>(SEXP x) {
116116
return convert_using_rfunction(x, "as.expression" ) ;
117117
}
118-
template<>
118+
template<>
119119
inline SEXP r_true_cast<LISTSXP>(SEXP x) {
120120
switch( TYPEOF(x) ){
121121
case LANGSXP:
122122
{
123-
Shield<SEXP> y( Rf_duplicate( x ));
123+
Shield<SEXP> y( Rf_duplicate( x ));
124124
SET_TYPEOF(y,LISTSXP) ;
125125
return y ;
126126
}
127127
default:
128128
return convert_using_rfunction(x, "as.pairlist" ) ;
129129
}
130130
}
131-
template<>
131+
template<>
132132
inline SEXP r_true_cast<LANGSXP>(SEXP x) {
133-
return convert_using_rfunction(x, "as.call" ) ;
133+
return convert_using_rfunction(x, "as.call" ) ;
134134
}
135135

136-
} // namespace internal
136+
} // namespace internal
137137

138-
template <int TARGET> SEXP r_cast( SEXP x) {
139-
return (TYPEOF(x)== TARGET) ? x : internal::r_true_cast<TARGET>(x) ;
138+
template <int TARGET> SEXP r_cast(SEXP x) {
139+
if (TYPEOF(x) == TARGET) {
140+
return x;
141+
} else {
142+
#ifndef RCPP_DONT_WARN_ON_COERCE
143+
Shield<SEXP> result( internal::r_true_cast<TARGET>(x) );
144+
Rf_warning("coerced object from '%s' to '%s'",
145+
CHAR(Rf_type2str(TYPEOF(x))),
146+
CHAR(Rf_type2str(TARGET))
147+
);
148+
return result;
149+
#else
150+
return internal::r_true_cast<TARGET>(x);
151+
#endif
152+
}
140153
}
141154

142155
} // namespace Rcpp

0 commit comments

Comments
 (0)