0

I am using C++ 14 on clang & gcc. I have an std::string which I need to convert to unsigned short I am doing it the following way.

unsigned short u_var = 1234;  //some default value
std::string str = "5678";      //some default value

u_var = (unsigned short) std::strtoul(str.c_str(), NULL, 0);

I found this from here.

However, I get the following warning doing this

Semantic issue
warning: use of old-style cast

The warning appears for both clang & gcc. What is wrong in what I doing? Is there is a better way to do this without any risk or a warning?

Also looking at the list of casting methods here, there seems to be no cast option available for std::string to unsigned short.

Community
  • 1
  • 1
TheWaterProgrammer
  • 7,055
  • 12
  • 70
  • 159
  • 1
    Does `static_cast(std::strtoul(str.c_str(), NULL, 0);)` help? It doesn't complain about conversion, it complains about the syntax. – luk32 Jan 03 '17 at 12:30
  • It's warning you that the cast you used, whose meaning is well-defined and perfectly appropriate as you've used it, might not be appropriate in some other context. – Pete Becker Jan 03 '17 at 12:49

3 Answers3

4

The problem is with the C-style cast (they are kinda risky). Use static_cast instead. Like:

u_var = static_cast< unsigned short >( std::strtoul(str.c_str(), NULL, 0) );

I'd also use std::stoul instead of std::strtoul, if it's possible (it's C++11)

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • seems like stoul is not supported in C++11 but yes, the static cast takes away the warning – TheWaterProgrammer Jan 03 '17 at 12:39
  • 1
    @SegmentationFault - `stoul` _is_ introduced in C++11, so you need to compile with a "modern" compiler and `-std=c++11`. At least according to `cppreference.com`. – Kiril Kirov Jan 03 '17 at 12:45
2

(unsigned short) <expression> is a C-style explicit cast, which is potentially unsafe as it tries to perform various conversions including reinterpret_cast and const_cast.

You should use static_cast for numerical conversions:

u_var = static_cast<unsigned short>(std::strtoul(str.c_str(), NULL, 0));
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
1

The warning appears for both clang & gcc. What is wrong in what I doing? Is there is a better way to do this without any risk or a warning?

compiler gives you an advise that its safier to use c++ style cast: static_cast<unsigned short>(...) instead of c style cast: (unsigned short)...

If you are using C++14 then you may consider using std::stoul function, in case of error it throws exception, which is easier to work with.

Also looking at the list of casting methods here, there seems to be no cast option available for std::string to unsigned short.

there is no standard cast for converting std::string to unsinged short, but with boost::lexical_cast it is possible: your code would look as follows :

try
{
   u_var = boost::lexical_cast<unsigned short>(str);
}
catch(const boost::bad_lexical_cast &)
{
   // error
}
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • so, do you recommend that using `std::stoul` is better than `std::strtoul` ? – TheWaterProgrammer Jan 03 '17 at 12:48
  • I dont have the option to use boost here. I have to strictly stay within `std::` options – TheWaterProgrammer Jan 03 '17 at 12:49
  • 1
    @SegmentationFault yes - that is because error checking for strtoul is not so obvious - you can find on this here: http://stackoverflow.com/questions/1640720/how-do-i-tell-if-the-c-function-atoi-failed-or-if-it-was-a-string-of-zeros. If you consider using std::stoul then check if your stl library actually supports it, as far as I remember android NDK does not. – marcinj Jan 03 '17 at 13:00