Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swprintf does not reset errno under Visual Studio 2013 #614

Closed
mihaitodor opened this issue Nov 24, 2017 · 4 comments
Closed

swprintf does not reset errno under Visual Studio 2013 #614

mihaitodor opened this issue Nov 24, 2017 · 4 comments

Comments

@mihaitodor
Copy link
Contributor

I have encountered an issue with errno remaining set to ERANGE when using this library under Windows. It turns out that the following code:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdlib>
#include <cstdio>

int main()
{
    int i = 10;
    wchar_t wrong[1]{};
    auto n1 = swprintf(wrong, 1, L"wrong %d", i);
    printf("%d %d\n", n1, errno);

    wchar_t right[100]{};
    auto n2 = swprintf(right, 100, L"fine %d", i);
    printf("%d %d\n", n2, errno);
}

when compiled with Visual Studio 2013 will output:

-1 34
7 34

and when compiled with Visual Studio 2017 will output:

-1 0
7 0

According to the documentation:

If execution is allowed to continue, these functions return -1 and set errno to EINVAL.

And, looking into the documentation for errno:

Always clear errno by calling _set_errno(0) immediately before a call that may set it, and check it immediately after the call.

Given this inconsistent behaviour, I am wondering if fmtlib should attempt to call _set_errno(0) after invoking such functions.

@vitaut
Copy link
Contributor

vitaut commented Nov 24, 2017

The fmt library doesn't use errno to communicate errors to the user, but it may call system functions that set errno. So you shouldn't rely on any particular value of errno after a call to a formatting function and nonzero value doesn't indicate a failure. I don't think it's a problem because according to the documentation that you quoted one should reset errno before calling system functions, not after.

@vitaut vitaut closed this as completed Nov 24, 2017
@mihaitodor
Copy link
Contributor Author

mihaitodor commented Nov 24, 2017

@vitaut Thank you for the quick reply. Just to clarify, does this mean that users of fmtlib need to be aware that using it can potentially change global state and treat it like any other system call that can alter errno? Otherwise, wouldn't it make sense to attempt to capture the original errno value when calling fmtlib functions and restore it before these functions exit?

@vitaut
Copy link
Contributor

vitaut commented Nov 24, 2017

Just to clarify, does this mean that users of fmtlib need to be aware that using it can potentially change global state and treat it like any other system call that can alter errno?

Technically yes, but it shouldn't really matter, because to use errno elsewhere one has to clear it anyway:

Always clear errno by calling _set_errno(0) immediately before a call that may set it, and check it immediately after the call.

So I don't think that preserving errno is something worth the trouble. It might be useful to document this though (PRs are welcome =)).

@mihaitodor
Copy link
Contributor Author

OK, thanks @vitaut! I opened a PR :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants