【问题标题】:Cerrno not working, but strerror working, in Xcode (11.6)Cerrno 不工作,但 strerror 工作,在 Xcode (11.6)
【发布时间】:2020-08-17 21:11:47
【问题描述】:

编辑: Strerror 似乎有效。例如,如果 errno = ERANGE,则输出“Result too large”。

问题依旧是errno没有从0变。


在 Xcode 中,我一直在尝试使用下面的短代码 cerrnostrerror。 Xcode 返回

sqrt(-1) = 南

未定义错误:0

而不是

sqrt(-1) = -nan

域外的数值参数,

例如 cpp.sh。

为什么会这样?

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>

using namespace std;

int main() {

  errno = 0;
  cout << "sqrt(-1) = " << sqrt(-1) << endl;
  cout << strerror(errno) << endl << endl;
       
  return(0); 
}

【问题讨论】:

  • 主要是为了满足我的好奇心(但可能会有所帮助),你能告诉我们你的编译器对math_errhandling 宏的值吗?例如添加这一行:cout &lt;&lt; "math_errhandling = " &lt;&lt; math_errhandling &lt;&lt; endl;?
  • 嗨,它添加了“math_errhandling = 2”。
  • That explains it 然后。
  • 好吧——问题就在这里!为了设置errno,该宏必须包含1。 (它应该是 3 以符合 C++11,IIRC)。但是如何解决它......不知道。
  • 您能否查看您的详细设置和/或编译器命令行选项以查看是否在任何地方设置了-fno-math-errno 选项;或查看您的 标头以获取 __NO_MATH_ERRNO__ 的定义。或者,尝试在 #include... 行之前添加 #undef __NO_MATH_ERRNO__

标签: c++ xcode compiler-errors c-strings


【解决方案1】:

当您想在操作后检查errno 时,您应该始终检查它,并可能存储它,在设置它的操作之后立即。如果您在该检查之间执行其他函数调用,即使是像打印到终端这样简单的事情,您可能会破坏errno

errno 变成0 的一个可能原因是它被包装在流表达式中,并且不能保证 iostream 不会通过其实现间接设置(或取消设置)errno

如果您想检查或打印errno 原因,您总是希望在打印之前存储结果。例如:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>

int main() {

  errno = 0;
  
  // store errno immediately after the computation
  const auto result = std::sqrt(-1);
  const auto err = errno;

  // then print
  std::cout << "sqrt(-1) = " << result << std::endl;
  std::cout << std::strerror(err) << std::endl << std::endl;
       
  return 0; 
}

编辑:从 OP 的 cmets 中的讨论来看,这似乎不是 errno 未设置的原因 - 而是由于 math_errhandling being set to 2。出于存档原因,我将这个答案保留在这里,因为由于此处描述的原因,原始帖子中的代码很容易看到此结果。

【讨论】:

  • 我的错;发布后不久,我看到了关于 math_errhandling 负责的讨论。这不是您特定问题的正确答案,但我仍然会保持这个答案,因为这是为什么errno 可能不是您所期望的不同的可能来源(以防其他人偶然发现这个问题)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
相关资源
最近更新 更多