Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

standard error messages in a std::string or in a const char *

62 views
Skip to first unread message

Soviet_Mario

unread,
Sep 10, 2019, 6:36:00 PM9/10/19
to
I'm striving with the translation of standard error codes
(returned by runtime functions), like "errno" codes in the
corresponding TEXTUAL DESCRIPTIONS.

I've seen perror () functions knows how to translate errno,
but it does not allow to return that description as a
string. Instead it "prints" to stderr, which is useless if
ones tries to bubble error messages in a chain of function
calls (with the aim : me, callee, don't know how to handle,
I bubble the message to you, the caller, and maybe you know
or THE USER might know).

perror must lookup some internal table where errno's values
are translated and the text returned (or copied to stderr).

How to get it in a string ?
thanks



--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)

Soviet_Mario

unread,
Sep 10, 2019, 6:37:42 PM9/10/19
to
Il 11/09/19 00:35, Soviet_Mario ha scritto:
> I'm striving with the translation of standard error codes
> (returned by runtime functions), like "errno" codes in the
> corresponding TEXTUAL DESCRIPTIONS.
>
> I've seen perror () functions knows how to translate errno,
> but it does not allow to return that description as a
> string. Instead it "prints" to stderr, which is useless if
> ones tries to bubble error messages in a chain of function
> calls (with the aim : me, callee, don't know how to handle,
> I bubble the message to you, the caller, and maybe you know
> or THE USER might know).
>
> perror must lookup some internal table where errno's values
> are translated and the text returned (or copied to stderr).
>
> How to get it in a string ?
> thanks
>
>
>

merd !
sorry ... I find this just now

https://linux.die.net/man/3/strerror

maybe will work ...
:\

Jorgen Grahn

unread,
Sep 11, 2019, 4:29:11 AM9/11/19
to
On Tue, 2019-09-10, Soviet_Mario wrote:
> Il 11/09/19 00:35, Soviet_Mario ha scritto:
>> I'm striving with the translation of standard error codes
>> (returned by runtime functions), like "errno" codes in the
>> corresponding TEXTUAL DESCRIPTIONS.
>>
>> I've seen perror () functions knows how to translate errno,
>> but it does not allow to return that description as a
>> string. Instead it "prints" to stderr, which is useless if
>> ones tries to bubble error messages in a chain of function
>> calls (with the aim : me, callee, don't know how to handle,
>> I bubble the message to you, the caller, and maybe you know
>> or THE USER might know).
>>
>> perror must lookup some internal table where errno's values
>> are translated and the text returned (or copied to stderr).
>>
>> How to get it in a string ?
>> thanks

> merd !
> sorry ... I find this just now
>
> https://linux.die.net/man/3/strerror
>
> maybe will work ...

It will do what the documentation says, and lots of people use it.
Note its limitations, though. It's not thread-safe, for example.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Juha Nieminen

unread,
Sep 11, 2019, 4:58:24 AM9/11/19
to
Jorgen Grahn <grahn...@snipabacken.se> wrote:
>> https://linux.die.net/man/3/strerror
>>
>> maybe will work ...
>
> It will do what the documentation says, and lots of people use it.
> Note its limitations, though. It's not thread-safe, for example.

What do you mean it's not thread-safe? AFAIK errno is thread-local
according to the standard.

Bonita Montero

unread,
Sep 11, 2019, 5:09:22 AM9/11/19
to
>>> https://linux.die.net/man/3/strerror
>>> maybe will work ...

>> It will do what the documentation says, and lots of people use it.
>> Note its limitations, though. It's not thread-safe, for example.

> What do you mean it's not thread-safe?
> AFAIK errno is thread-local according to the standard.

http://man7.org/linux/man-pages/man3/errno.3.html
"errno is thread-local; setting it in one thread does not affect
its value in any other thread."

Bonita Montero

unread,
Sep 11, 2019, 5:37:40 AM9/11/19
to
>> What do you mean it's not thread-safe?
>> AFAIK errno is thread-local according to the standard.

> http://man7.org/linux/man-pages/man3/errno.3.html
> "errno is thread-local; setting it in one thread does not affect
> its value in any other thread."

From the 2007 POSIX draft:
"3.396 Thread
A single flow of control within a process. Each thread has its
own thread ID, scheduling priority and policy, errno value ..."

Keith Thompson

unread,
Sep 11, 2019, 5:37:40 AM9/11/19
to
errno is thread-local. That doesn't necessarily mean that strerror()
is thread-safe. For example, a conforming implementation could
always return a pointer to the same static buffer, initialized
with the appropriate message before it returns. And at least one
implementation (x86_64-w64-mingw32-gcc) appears to do exactly that.

N1570 7.24.6.2p3:

The strerror function is not required to avoid data races with
other calls to the strerror function. The implementation shall
behave as if no library function calls the strerror function.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Bonita Montero

unread,
Sep 11, 2019, 5:48:03 AM9/11/19
to
There's strerror_r, which is thread-safe.

Öö Tiib

unread,
Sep 11, 2019, 7:43:40 AM9/11/19
to
On Wednesday, 11 September 2019 12:48:03 UTC+3, Bonita Montero wrote:
> There's strerror_r, which is thread-safe.

Somewhere there is strerror_r but not in C++ standard. In C++ standard
there was added strerror_s by C++11 but it may be is deprecated again.

James Kuyper

unread,
Sep 11, 2019, 8:27:30 AM9/11/19
to
On 9/11/19 7:43 AM, Öö Tiib wrote:
> On Wednesday, 11 September 2019 12:48:03 UTC+3, Bonita Montero wrote:
>> There's strerror_r, which is thread-safe.
>
> Somewhere there is strerror_r but not in C++ standard. ...

Such a function is specified by POSIX, which doesn't help those
targeting non-POSIX systems.

> ... In C++ standard
> there was added strerror_s by C++11 but it may be is deprecated again.

It is still mentioned in N4659.pdf, dated 2017-03-01. It is described in
20.1.5.2p10 as a carry-over from C. There is no other description,
you're supposed to cross-reference the C standard for that.

The description of sterror_s() in the C standard (C11 K3.7.4.2) does
not, itself, say anything about threads. It simply lacks any clause
comparable to the one in the description of sterror() description which
says "The strerror function is not required to avoid data races with
other calls to the strerror function." (C11 7.24.6.2p3). That's
sufficient, since "Unless explicitly stated otherwise in the detailed
descriptions that follow, library functions shall prevent data races."
(C11 7.1.4p5).

Just in case you didn't notice that omission, footnote 312 on the
description of strerror() says "The strerror_s function can be used
instead to avoid data races.".

Manfred

unread,
Sep 11, 2019, 8:56:57 AM9/11/19
to
strerror_s is indeed part of annex K, which has become more and more
controversial, and some implementations (notably glibc) do not support it.
However, a good indication that it is thread safe comes from its
interface: instead of returning a pointer to an internal string buffer,
it requires a writable buffer to be provided by the caller.

Daniel

unread,
Sep 11, 2019, 10:00:51 AM9/11/19
to
On Wednesday, September 11, 2019 at 8:56:57 AM UTC-4, Manfred wrote:
>
> strerror_s is indeed part of annex K, which has become more and more
> controversial, and some implementations (notably glibc) do not support it.
> However, a good indication that it is thread safe comes from its
> interface: instead of returning a pointer to an internal string buffer,
> it requires a writable buffer to be provided by the caller.

There appears to be a lot to say about some very simple functions! e.g.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm

I hadn't known about this: "since virtually every function in the Bounds
checking library relies on a single process-global runtime-constraint handler,
the APIs are ill-suited for multi-threaded components."

Daniel




Soviet_Mario

unread,
Sep 11, 2019, 11:44:10 AM9/11/19
to
Il 11/09/19 10:58, Juha Nieminen ha scritto:
maybe errno is such, but I think strerror should return a
pointer to an internal buffer which it alone reserves the
right to modify on subsequent calls.
In this buffer the function should copy the message (or
maybe it just sets the pointer to a more risky internally
maintained table ... much faster).

So if different threads calls the functions without notice,
one thread could get the error generated from the other ...
That's the little I have understood


but my main problem is : even including all possible
headers, QT IDE does not see strerror prototype.

Normally when I include sth, within seconds the intellisense
starts popping up the parameters type-info and return value.
Here it does not do so, and underlines the name in red as
unknown :\ :\

Paavo Helde

unread,
Sep 11, 2019, 12:23:54 PM9/11/19
to
On 11.09.2019 18:43, Soviet_Mario wrote:
>
> but my main problem is : even including all possible headers, QT IDE
> does not see strerror prototype.

"All possible headers" are not needed, man strerror clearly says it is
declared in <string.h>.

Thiago Adams

unread,
Sep 11, 2019, 12:45:12 PM9/11/19
to
On Wednesday, September 11, 2019 at 6:37:40 AM UTC-3, Keith Thompson wrote:
> Juha Nieminen rites:
> > Jorgen Grahn wrote:
> >>> https://linux.die.net/man/3/strerror
> >>>
> >>> maybe will work ...
> >>
> >> It will do what the documentation says, and lots of people use it.
> >> Note its limitations, though. It's not thread-safe, for example.
> >
> > What do you mean it's not thread-safe? AFAIK errno is thread-local
> > according to the standard.
>
> errno is thread-local. That doesn't necessarily mean that strerror()
> is thread-safe. For example, a conforming implementation could
> always return a pointer to the same static buffer, initialized
> with the appropriate message before it returns. And at least one
> implementation (x86_64-w64-mingw32-gcc) appears to do exactly that.
>
> N1570 7.24.6.2p3:
>
> The strerror function is not required to avoid data races with
> other calls to the strerror function. The implementation shall
> behave as if no library function calls the strerror function.
>

I recently came across this subject as well and I was wondering
why strerror is not thread safe. The answer I gave to myself is that
is probably because it uses locales. It is just a guess.





Soviet_Mario

unread,
Sep 11, 2019, 1:20:07 PM9/11/19
to
Il 11/09/19 18:23, Paavo Helde ha scritto:
thanks a lot.
I included C++ like headers, among them "plain" <string>
and guess what ?
the C++ header DONT have a strerror prototype.
But later I replaced that header with the C-like you
suggested, and exploring the code I found the prototype.

Many thanks Paavo !

Paavo Helde

unread,
Sep 11, 2019, 1:32:32 PM9/11/19
to
On 11.09.2019 20:19, Soviet_Mario wrote:
> Il 11/09/19 18:23, Paavo Helde ha scritto:
>> On 11.09.2019 18:43, Soviet_Mario wrote:
>>>
>>> but my main problem is : even including all possible headers, QT IDE
>>> does not see strerror prototype.
>>
>> "All possible headers" are not needed, man strerror clearly says it is
>> declared in <string.h>.
>>
>
> thanks a lot.
> I included C++ like headers, among them "plain" <string>
> and guess what ?
> the C++ header DONT have a strerror prototype.

That's expected. The C++ equivalent of <string.h> is <cstring>, not
<string>. And even with <cstring> you should call std::strerror(), not
strerror().

Thiago Adams

unread,
Sep 11, 2019, 1:39:41 PM9/11/19
to
You can create our own thread safe function replacing strerror.

int main(void)
{
printf("const char* mystrerror(int i){\n");
printf(" switch(i) {\n");
for (int i = 0; i < 134; i++)
{
printf(" case %d: return \"%s\";\n", i, strerror(i));
}
printf(" }\n");
printf(" return \"Unknown error\";\n");
printf("}");
}

I did this for curiosity in windows and linux.
Window prints "Unknown error" error >= 43
Linux prints "Unknown error 134" error >= 134

I also printed side by side. (I think is to big to put here)
There are some diferences for instance:

Linux | Windows
7 Argument list too long | Arg list too long
35 Resource deadlock avoided | Unknown error

etc..

James Kuyper

unread,
Sep 11, 2019, 7:50:20 PM9/11/19
to
On 9/11/19 1:19 PM, Soviet_Mario wrote:
> Il 11/09/19 18:23, Paavo Helde ha scritto:
>> On 11.09.2019 18:43, Soviet_Mario wrote:
>>>
>>> but my main problem is : even including all possible
>>> headers, QT IDE
>>> does not see strerror prototype.
>>
>> "All possible headers" are not needed, man strerror clearly
>> says it is declared in <string.h>.
>>
>
> thanks a lot.
> I included C++ like headers, among them "plain" <string>
> and guess what ?
> the C++ header DONT have a strerror prototype.

The C++ header <string.h> has essentially the same contents as the C
header of the same name. The C++ header <cstring> differs from
<string.h> mainly in that the functions are declared inside the std::
namespace.

Keith Thompson

unread,
Sep 11, 2019, 8:11:25 PM9/11/19
to
James Kuyper <james...@alumni.caltech.edu> writes:
[...]
> The C++ header <string.h> has essentially the same contents as the C
> header of the same name. The C++ header <cstring> differs from
> <string.h> mainly in that the functions are declared inside the std::
> namespace.

<string.h> defines strerror and other identifiers in the global
namespace, and may optionally define them in the std namespace, while
<cstring> defines them in the std namespace and may optionally define
them in the global namespace.

(I dislike this, but that's the way the language specifies it.)

Also, the <*.h> C headers are deprecated as of C++17.

James Kuyper

unread,
Sep 11, 2019, 8:24:03 PM9/11/19
to
On 9/11/19 8:11 PM, Keith Thompson wrote:
...
> Also, the <*.h> C headers are deprecated as of C++17.

I hadn't noticed that.

David Brown

unread,
Sep 12, 2019, 5:22:07 AM9/12/19
to
It is not going to make any practical difference, as any real-world C++
implementation also supports C, and has the C headers. I guess the aim
is to move C++ programmers to use the std:: namespace for standard C
functions as much as possible, reducing the global namespace usage.

I don't know how that works for macros defined in C standard headers -
they can't go into a namespace.

Jorgen Grahn

unread,
Sep 12, 2019, 6:21:47 AM9/12/19
to
On Wed, 2019-09-11, Keith Thompson wrote:
> Juha Nieminen <nos...@thanks.invalid> writes:
>> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>>>> https://linux.die.net/man/3/strerror
>>>>
>>>> maybe will work ...
>>>
>>> It will do what the documentation says, and lots of people use it.
>>> Note its limitations, though. It's not thread-safe, for example.
>>
>> What do you mean it's not thread-safe? AFAIK errno is thread-local
>> according to the standard.
>
> errno is thread-local.

And strerror doesn't use errno.

> That doesn't necessarily mean that strerror()
> is thread-safe. For example, a conforming implementation could
> always return a pointer to the same static buffer, initialized
> with the appropriate message before it returns. And at least one
> implementation (x86_64-w64-mingw32-gcc) appears to do exactly that.
>
> N1570 7.24.6.2p3:
>
> The strerror function is not required to avoid data races with
> other calls to the strerror function. The implementation shall
> behave as if no library function calls the strerror function.

That was what I was referring to. Sorry for being unclear.

Soviet_Mario

unread,
Sep 12, 2019, 7:05:51 AM9/12/19
to
Il 12/09/19 12:21, Jorgen Grahn ha scritto:
> On Wed, 2019-09-11, Keith Thompson wrote:
>> Juha Nieminen <nos...@thanks.invalid> writes:
>>> Jorgen Grahn <grahn...@snipabacken.se> wrote:
>>>>> https://linux.die.net/man/3/strerror
>>>>>
>>>>> maybe will work ...
>>>>
>>>> It will do what the documentation says, and lots of people use it.
>>>> Note its limitations, though. It's not thread-safe, for example.
>>>
>>> What do you mean it's not thread-safe? AFAIK errno is thread-local
>>> according to the standard.
>>
>> errno is thread-local.
>
> And strerror doesn't use errno.


one can always pass errno to it ... but it does not strictly
guarantee that it will return the message associated with
THAT particular errno. Elsewhere some other caller could
have made another call and each receive mixed or the same
response depending on timing.


>
>> That doesn't necessarily mean that strerror()
>> is thread-safe. For example, a conforming implementation could
>> always return a pointer to the same static buffer, initialized
>> with the appropriate message before it returns. And at least one
>> implementation (x86_64-w64-mingw32-gcc) appears to do exactly that.
>>
>> N1570 7.24.6.2p3:
>>
>> The strerror function is not required to avoid data races with
>> other calls to the strerror function. The implementation shall
>> behave as if no library function calls the strerror function.
>
> That was what I was referring to. Sorry for being unclear.
>
> /Jorgen
>


--

Soviet_Mario

unread,
Sep 12, 2019, 7:08:46 AM9/12/19
to
Il 11/09/19 19:32, Paavo Helde ha scritto:
> On 11.09.2019 20:19, Soviet_Mario wrote:
>> Il 11/09/19 18:23, Paavo Helde ha scritto:
>>> On 11.09.2019 18:43, Soviet_Mario wrote:
>>>>
>>>> but my main problem is : even including all possible
>>>> headers, QT IDE
>>>> does not see strerror prototype.
>>>
>>> "All possible headers" are not needed, man strerror
>>> clearly says it is
>>> declared in <string.h>.
>>>
>>
>> thanks a lot.
>> I included C++ like headers, among them "plain" <string>
>> and guess what ?
>> the C++ header DONT have a strerror prototype.
>
> That's expected. The C++ equivalent of <string.h> is
> <cstring>, not <string>.

ahhhh ! Got it. Strangely I had included the (useless)
<cerrno> but not completely consciously, and did not include
<cstring>

> And even with <cstring> you should
> call std::strerror(), not strerror().

it allowed plain strerror, maybe due to the fact I have
included a using namespace std directive. I will remove it
anyway

tnx again

Thiago Adams

unread,
Sep 12, 2019, 7:29:46 AM9/12/19
to
On Thursday, September 12, 2019 at 8:08:46 AM UTC-3, Soviet_Mario wrote:
...
> ahhhh ! Got it. Strangely I had included the (useless)
> <cerrno> but not completely consciously, and did not include

C++ standard is creating differences from the same C header.

For instance:
C++ <cerrno> defines a lot of POSIX error codes.
"E2BIG, EACCES, ..., EXDEV"
https://en.cppreference.com/w/cpp/error/errno_macros

And C defines only EDOM, EILSEQ and ERANGE
https://en.cppreference.com/w/c/error/errno_macros





James Kuyper

unread,
Sep 12, 2019, 7:31:54 AM9/12/19
to
On 9/12/19 5:21 AM, David Brown wrote:
> On 12/09/2019 02:23, James Kuyper wrote:
>> On 9/11/19 8:11 PM, Keith Thompson wrote:
>> ...
>>> Also, the <*.h> C headers are deprecated as of C++17.
>>
>> I hadn't noticed that.
>>
>
> It is not going to make any practical difference, as any real-world C++
> implementation also supports C, and has the C headers. ...

If they're deprecated now, it's a warning that they may be removed in
the future. If they are removed someday, that will give implementations
permission to no longer provide them, and sooner or later an
implementation will be created that doesn't. That date might be a long
time coming, but when it does, it will mark a major step in the
separation of C++ from C.

> ... I guess the aim
> is to move C++ programmers to use the std:: namespace for standard C
> functions as much as possible, reducing the global namespace usage.
>
> I don't know how that works for macros defined in C standard headers -
> they can't go into a namespace.

How it works is that they don't go in a namespace.

Manfred

unread,
Sep 12, 2019, 9:44:40 AM9/12/19
to
Which is not really working, IMVVHO - I mean they compile and do the
job, but you end up with a mixture of std:: and non-std-qualified names
which I find ungood at best.
How bad it is varies from one implementation to one other, though.

Keith Thompson

unread,
Sep 12, 2019, 5:41:33 PM9/12/19
to
The C standard only requires EDOM, EILSEQ, and ERANGE, but C
implementations can, and commonly do, define additional macros.

Both C and POSIX specifically permit additional E* macros to
be defined. I don't see such a permission in the C++ standard,
though I could be missing it.

(I'm a little surprised C++ mandates the POSIX error codes, given
that C++ can be implemented on non-POSIX systems.)
0 new messages