`setlocale` sets `errno` to `0`

The setlocale C/C++ function writes the global variable errno to 0. In Linux it doesn't have this behavior and the documentation doesn't says anything about setting errno (as I understand, no function should set errno to 0

The following code allows to reproduce it

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
  ifstream myStream;
  myStream.open("NONEXISTENT.txt", ios::in);
  cout << errno << endl;
  setlocale(LC_ALL, "en_US.UTF-8");
  cout << errno << endl;
}
// Output:
// 2
// 0

I don't think is a compiler issue as the error also happens with gcc but rather a libc issue.

Replies

As a general rule, errno is only valid immediately after a call that’s documented to set it. If you call into library code that says nothing about errno, you can’t assume that it preserves its value.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

If you call into library code that says nothing about errno, you can’t assume that it preserves its value.

But POSIX says that no function sets it to zero:

https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html

No function in this volume of POSIX.1-2017 shall set errno to 0

Does macOS claim to comply with (this version of) POSIX?

Oh hey, woulda you look at that. What a weird requirement. Sure, you should feel free to file a bug about that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"