[cfe-commits] [libcxx] r173172 - in /libcxx/trunk: include/locale src/string.cpp
Howard Hinnant
hhinnant at apple.com
Tue Jan 22 12:41:06 PST 2013
On Jan 22, 2013, at 3:22 PM, Joerg Sonnenberger <joerg at britannica.bec.de> wrote:
> On Tue, Jan 22, 2013 at 05:26:09PM -0000, Howard Hinnant wrote:
>> Author: hhinnant
>> Date: Tue Jan 22 11:26:08 2013
>> New Revision: 173172
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=173172&view=rev
>> Log:
>> Saleem Abdulrasool: If errno is defined as volatile int, the qualifier differences can cause
>> template typename deductions on swap<> (used in string.cpp).
>
> Why are you using swap<> in first place? errno is either an integer or
> lvalue of int type and a plain assignment should be exactly what is
> desired here?
>
> Joerg
Hmmm.. just looking at float stof(const string& str, size_t* idx) as an example. If I didn't use swap, I think this is how I would code it:
float
stof(const string& str, size_t* idx)
{
char* ptr;
const char* const p = str.c_str();
typename remove_reference<decltype(errno)>::type errno_save = errno;
errno = 0;
float r = strtof(p, &ptr);
{
typename remove_reference<decltype(errno)>::type tmp = errno;
errno = errno_save;
errno_save = tmp;
}
if (errno_save == ERANGE)
throw out_of_range("stof: out of range");
if (ptr == p)
throw invalid_argument("stof: no conversion");
if (idx)
*idx = static_cast<size_t>(ptr - p);
return r;
}
Although here's another possibility:
float
stof(const string& str, size_t* idx)
{
char* ptr;
const char* const p = str.c_str();
typename remove_reference<decltype(errno)>::type errno_save = errno;
errno = 0;
float r = strtof(p, &ptr);
if (errno == ERANGE)
{
errno = errno_save;
throw out_of_range("stof: out of range");
}
errno = errno_save;
if (ptr == p)
throw invalid_argument("stof: no conversion");
if (idx)
*idx = static_cast<size_t>(ptr - p);
return r;
}
Are either of these superior to:
float
stof(const string& str, size_t* idx)
{
char* ptr;
const char* const p = str.c_str();
typename remove_reference<decltype(errno)>::type errno_save = errno;
errno = 0;
float r = strtof(p, &ptr);
swap(errno, errno_save);
if (errno_save == ERANGE)
throw out_of_range("stof: out of range");
if (ptr == p)
throw invalid_argument("stof: no conversion");
if (idx)
*idx = static_cast<size_t>(ptr - p);
return r;
}
?
<shrug>
I'm not seeing any dramatic differences between any of them. I guess if we don't use swap then the first two could use int instead of the more complicated typename remove_reference<decltype(errno)>::type. I'm not really seeing any issues besides stylistic.
Howard
More information about the cfe-commits
mailing list