Concatenating strings and numeric values in the scripting language

Hi all

The scripting language permits to concatenate strings, for instance: "firststring" + "secondstring" creates a new string with contents "firststringsecondstring". Yet, concatenating strings and ints as in C++ is not enabled by default in RTT. To enable this feature, I am trying to extend the toolkit with the following C++ code:

        template <class T>
    struct string_numeric_concatenation : public std::binary_function<std::string, T, std::string> {
        std::string operator()(const std::string& s, T t) const {
            std::ostringstream oss(s);
            oss << t;
            return oss.str();
        }
    };
Then I declare my new string concatenation operators:

        operators()->add(newBinaryOperator("+", string_numeric_concatenation0()));
        operators()->add(newBinaryOperator("+", string_numeric_concatenation1()));
Nevertheless, when I try to concatenate "mystring" with 3 for instance, it does not work and I get the following warning:

        In Task Ressac[R]. (Status of last Command : none )
        (type 'ls' for context info) :"mystring" + 3
             Got :"mystring" + 3
        814.101 [ Warning][Activity] Conversion from int to string
        = mystring
Moreover, in big scripts, it seems the integer (3 for instance) randomly writes somewhere in forbidden memory locations. I am wondering what is happening here, since using ostringstreams to concatenate strings and numeric values is commonly used in C++ without problems. Does Orocos preprocess the integer before sending it to my concatenation operator?

All the best, Florent

Concatenating strings and numeric values in the scripting langua

On Thursday 22 April 2010 10:24:57 florent [dot] teichteil [..] ... wrote:
> Hi all
>
> The scripting language permits to concatenate strings, for instance:
> "firststring" + "secondstring" creates a new string with contents
> "firststringsecondstring". Yet, concatenating strings and ints as in C++
> is not enabled by default in RTT. To enable this feature, I am trying to
> extend the toolkit with the following C++ code:
>
> template <class T>
> struct string_numeric_concatenation : public
> std::binary_function<std::string, T, std::string> { std::string
> operator()(const std::string& s, T t) const {
> std::ostringstream oss(s);
> oss << t;
> return oss.str();
> }
> };

This looks wrong. The binary function inheritance should have different
template arguments, reflecting the arguments of operator():

template <class T>
struct string_numeric_concatenation 
 : public std::binary_function<std::string, const std::string&, T> { 
  std::string operator()(const std::string& s, T t) const {
 			std::ostringstream oss(s);
 			oss << t;
 			return oss.str();
  }
};

>
> Then I declare my new string concatenation operators:
>
> operators()->add(newBinaryOperator("+",
> string_numeric_concatenation<double>()));
> operators()->add(newBinaryOperator("+",
> string_numeric_concatenation<int>()));
>
> Nevertheless, when I try to concatenate "mystring" with 3 for instance, it
> does not work and I get the following warning:
>
> In Task Ressac[R]. (Status of last Command : none )
> (type 'ls' for context info) :"mystring" + 3
> Got :"mystring" + 3
> 814.101 [ Warning][Activity] Conversion from int to string
> = mystring

So this might be due to the wrong template ordering...

>
> Moreover, in big scripts, it seems the integer (3 for instance) randomly
> writes somewhere in forbidden memory locations. I am wondering what is
> happening here, since using ostringstreams to concatenate strings and
> numeric values is commonly used in C++ without problems. Does Orocos
> preprocess the integer before sending it to my concatenation operator?

No. What you wish for must be possible... Did you check your code with
valgrind ?

If it works, please submit a patch, I'll add it to the RTT.

Peter

concatenating strings and numbers: bug in Orocos

According to the standard template library API (http://www.cplusplus.com/reference/std/functional/binary_function/), the template arguments of the binary function inheritance are in the right order in my code. Actually, Peter's proposition is rejected by the compiler.
So it looks like a bug in Orocos.

concatenating strings and numbers: bug in Orocos

According to the standard template library API (http://www.cplusplus.com/reference/std/functional/binary_function/), the template arguments of the binary function inheritance are in the right order in my code. Actually, Peter's proposition is rejected by the compiler. So it looks like a bug in Orocos.

concatenating strings and numbers: bug in Orocos

On Thursday 10 June 2010 13:45:36 florent [dot] teichteil [..] ... wrote:
> According to the standard template library API
> (http://www.cplusplus.com/reference/std/functional/binary_function/), the
> template arguments of the binary function inheritance are in the right
> order in my code. Actually, Peter's proposition is rejected by the
> compiler. So it looks like a bug in Orocos.

You are correct. what happens is that the line:

"mystring" + 3

is interpreted as:

"mystring" + string(3)

Since it *first* tries to use operator+(string,string) and RTT defines a
constructor int->string, which is then used. It shouldn't cause segfaults as
you report, so a valgrind trace of that case would be helpful.

The first shot at solving this is moving the lines

  operators()->add(newBinaryOperator("+", 
string_numeric_concatenation<double>()));
  operators()->add(newBinaryOperator("+", 
string_numeric_concatenation<int>()));

Higher in the RealTimeToolkit.cpp file, such that they precede the "+" operator
for (string,string). The scripting 'tries' all operators in the order they are
listed. This is crap, and can be solved (using TypeInfo matching), but not a
priority right now...

I suspect also that automatic conversion will kick in for the double/int case
and that the int will always be converted to a double.

Peter

concatenating strings and numbers: bug in Orocos

On Thursday 17 June 2010 14:14:56 Peter Soetens wrote:
> On Thursday 10 June 2010 13:45:36 florent [dot] teichteil [..] ... wrote:
> > According to the standard template library API
> > (http://www.cplusplus.com/reference/std/functional/binary_function/),
> > the template arguments of the binary function inheritance are in the
> > right order in my code. Actually, Peter's proposition is rejected by the
> > compiler. So it looks like a bug in Orocos.
>
> You are correct. what happens is that the line:
>
>

> "mystring" + 3
> 

>
> is interpreted as:
>
>
> "mystring" + string(3)
> 

>
> Since it *first* tries to use operator+(string,string) and RTT defines a
> constructor int->string, which is then used. It shouldn't cause segfaults
> as you report, so a valgrind trace of that case would be helpful.
>
> The first shot at solving this is moving the lines
>
>
>   operators()->add(newBinaryOperator("+",
> string_numeric_concatenation<double>()));
>   operators()->add(newBinaryOperator("+",
> string_numeric_concatenation<int>()));
> 

>
> Higher in the RealTimeToolkit.cpp file, such that they precede the "+"
> operator for (string,string). The scripting 'tries' all operators in the
> order they are listed. This is crap, and can be solved (using TypeInfo
> matching), but not a priority right now...
>

But since it can be easily solved, here's a patch for the 1.x line. First
looks for an exact match, and if none found, then tries to auto-convert. In
this way, the order is no longer important.

Please report if this fixes your problem.

Peter

concatenating strings and numbers: bug in Orocos

The above patch from Peter is working on my install (RTT 1.10.4):

In Task Deployer[S]. (Status of last Command : none )
 (type 'ls' for context info) :"toto" + 3
      Got :"toto" + 3
 = toto3

I attach the patch again (operator-matching.patch).

I join a complementary patch (rtt_string_ops.patch) adding '+' operations to the RealTimeToolkit to concatenate strings with basic scripting types.

---
Charles.

concatenating strings and numbers: bug in Orocos

The above patch from Peter is working on my install (RTT 1.10.4):

In Task Deployer[S]. (Status of last Command : none )
 (type 'ls' for context info) :"toto" + 3
      Got :"toto" + 3
 = toto3

I attach the patch again (operator-matching.patch).

I join a complementary patch (rtt_string_ops.patch) adding '+' operations to the RealTimeToolkit to concatenate strings with basic scripting types.

--- Charles.

concatenating strings and numbers: bug in Orocos

On Wednesday 13 October 2010 11:30:10 charles [dot] lesire [..] ... wrote:
> The above patch from Peter is working on my install (RTT 1.10.4):
>
>

> In Task Deployer[S]. (Status of last Command : none )
>  (type 'ls' for context info) :"toto" + 3
>       Got :"toto" + 3
>  = toto3
> 

>
> I attach the patch again (operator-matching.patch).
>
> I join a complementary patch (rtt_string_ops.patch) adding '+' operations
> to the RealTimeToolkit to concatenate strings with basic scripting types.

Thanks for the update. You could slightly improve the patch by streaming
'boolalpha' in the stringstream such that bools are printed as 'true' or
'false':

oss << std::boolalpha << s << t;

I'll apply them as-is, and add another patch with a unit test and the above
improvement. Ok ?

Peter

concatenating strings

Thanks a lot for the patch. Actually, expression such as 'string("blabla") + 1' systematically results in a segmentation fault, even in the deployer-gnulinux provided with orocos-rtt. Outputs of gdb or valgrind are simply too long to be posted.

concatenating strings

I have just discovered a workaround that raises new worrying questions about correctness of orocos' code. First, I removed Peter's patch, since it caused immediate segmentation faults when calling my '+' operator. It means that Orocos' treatment of '+' operators and strings is still strange. Then, because my '+' operator does not work for unknown reasons, I implemented a new 'string' constructor as follows:

template <class T> std::string stringConcatenateNumber(const std::string& s, T t) {

    std::ostringstream oss(s);
    oss << t;
    return oss.str();
}

types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<double>)); types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<int>)); types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<bool>));

Now, if I enter the command 'string("blabla", 1)', I get "1labla" in the deployer... But if I change the instruction "std::ostringstream oss(s);" by instructions "std::ostringstream oss; oss << s;", I get the intended output in the deployer: "blabla1". From my understanding of the standard C++ library, these instructions should be equivalent. I have used the first version in many codes in the past without problems. But in Orocos, the ostringstream constructor seems to behave differently, like if the input string was not recopied into the ostringstream object's buffer. Yet, the standard clearly says that the input string must be recopied into the ostringstream object's buffer. Does Orocos change the behavior of standard classes?

concatenating strings

On Wednesday 01 September 2010 11:45:58 florent [dot] teichteil [..] ... wrote:
> I have just discovered a workaround that raises new worrying questions
> about correctness of orocos' code. First, I removed Peter's patch, since
> it caused immediate segmentation faults when calling my '+' operator. It
> means that Orocos' treatment of '+' operators and strings is still
> strange. Then, because my '+' operator does not work for unknown reasons,
> I implemented a new 'string' constructor as follows:
>
> template <class T>
> std::string stringConcatenateNumber(const std::string& s, T t) {
> std::ostringstream oss(s);
> oss << t;
> return oss.str();
> }
>
> types()->type("string")->addConstructor(newConstructor(&stringConcatenateNu
> mber<double>));
> types()->type("string")->addConstructor(newConstructor(&stringConcatenateN
> umber<int>));
> types()->type("string")->addConstructor(newConstructor(&stringConcatenateN
> umber<bool>));
>
> Now, if I enter the command 'string("blabla", 1)', I get "1labla" in the
> deployer... But if I change the instruction "std::ostringstream oss(s);"
> by instructions "std::ostringstream oss; oss << s;", I get the intended
> output in the deployer: "blabla1". From my understanding of the standard
> C++ library, these instructions should be equivalent. I have used the
> first version in many codes in the past without problems. But in Orocos,
> the ostringstream constructor seems to behave differently, like if the
> input string was not recopied into the ostringstream object's buffer. Yet,
> the standard clearly says that the input string must be recopied into the
> ostringstream object's buffer. Does Orocos change the behavior of standard
> classes?

That's impossible. The language (and the std library) prevent that.

I have no time yet to reproduce your issue, but it looks like the problem is
with how you use the standard library (or how it was implemented). I'm sorry
the '+' experiment segfaults, it should be possible in practice.

Peter

concatenating strings and numbers: bug in Orocos

Thanks a lot for the patch. Actually, expression such as 'string("blabla") + 1' systematically results in a segmentation fault, even in the deployer-gnulinux provided with orocos-rtt. Outputs of gdb or valgrind are simply too long to be posted.

concatenating strings

I have just discovered a workaround that raises new worrying questions about correctness of orocos' code. First, I removed Peter's patch, since it caused immediate segmentation faults when calling my '+' operator. It means that Orocos' treatment of '+' operators and strings is still strange. Then, because my '+' operator does not work for unknown reasons, I implemented a new 'string' constructor as follows:

template <class T>
std::string stringConcatenateNumber(const std::string& s, T t) {
std::ostringstream oss(s);
oss << t;
return oss.str();
}

types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<double>));
types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<int>));
types()->type("string")->addConstructor(newConstructor(&stringConcatenateNumber<bool>));

Now, if I enter the command 'string("blabla", 1)', I get "1labla" in the deployer... But if I change the instruction "std::ostringstream oss(s);" by instructions "std::ostringstream oss; oss << s;", I get the intended output in the deployer: "blabla1". From my understanding of the standard C++ library, these instructions should be equivalent. I have used the first version in many codes in the past without problems. But in Orocos, the ostringstream constructor seems to behave differently, like if the input string was not recopied into the ostringstream object's buffer. Yet, the standard clearly says that the input string must be recopied into the ostringstream object's buffer. Does Orocos change the behavior of standard classes?

Concatenating strings and numeric values in the scripting langua

Hi all

The scripting language permits to concatenate strings, for instance: "firststring" + "secondstring" creates a new string with contents "firststringsecondstring". Yet, concatenating strings and ints as in C++ is not enabled by default in RTT. To enable this feature, I am trying to extend the toolkit with the following C++ code:

template <class T>
struct string_numeric_concatenation : public std::binary_function<std::string, T, std::string> {
std::string operator()(const std::string& s, T t) const {
std::ostringstream oss(s);
oss << t;
return oss.str();
}
};

Then I declare my new string concatenation operators:

operators()->add(newBinaryOperator("+", string_numeric_concatenation<double>()));
operators()->add(newBinaryOperator("+", string_numeric_concatenation<int>()));

Nevertheless, when I try to concatenate "mystring" with 3 for instance, it does not work and I get the following warning:

In Task Ressac[R]. (Status of last Command : none )
(type 'ls' for context info) :"mystring" + 3
Got :"mystring" + 3
814.101 [ Warning][Activity] Conversion from int to string
= mystring

Moreover, in big scripts, it seems the integer (3 for instance) randomly writes somewhere in forbidden memory locations. I am wondering what is happening here, since using ostringstreams to concatenate strings and numeric values is commonly used in C++ without problems. Does Orocos preprocess the integer before sending it to my concatenation operator?

All the best,
Florent