【问题标题】:What is the type of the errno variable in C++?C++中errno变量的类型是什么?
【发布时间】:2017-11-28 15:20:55
【问题描述】:

我正在使用 C++ 进行一些系统编程,我想将 linux 系统中的 errno 变量传递给我的异常处理程序。您可以在此处查看示例代码 https://pastebin.com/ppgMc8Hj

#include <sys/stat.h>
#include <cerrno>
#include <iostream>
#include <cstring>

std::string errorString(int errno){
    return std::strerror(errno);
}

int main(){
    struct stat sb;
    errno = 0;
    if(stat("/jdfj/", &sb)){
        errorString(errno);
    }
    else{
        std::cout << std::boolalpha << S_ISDIR(sb.st_mode) << std::endl;
    }
}

但它会返回这样的错误

In function 'int main()': 
 14:26: error: invalid conversion from 'int' to 'int* (*)()' [-fpermissive] 
  6:13: note: initializing argument 1 of 'std::string errorString(int* (*)())'.

我在这里看到http://en.cppreference.com/w/cpp/string/byte/strerror 从 errno 返回字符串的标准函数接受一个 int 作为参数。 我的问题是

  1. 如果是 int 类型为什么不能在上面的代码中工作?
  2. 如果不是,它是什么类型?

【问题讨论】:

  • 即使是最随意的搜索也显示“errno 是用于...的预处理器宏”

标签: c++ errno


【解决方案1】:

errno 是一个实现定义的宏,它扩展为int 类型的表达式。

问题是您使用名称errno 作为您的函数参数,这是不允许的。因为名称errno 是一个宏,所以它被扩展了。对我来说,结果是std::string errorString(int (*_errno()))。如果您更改参数名称,您的 sn-p 工作正常。

std::string errorString(int error_num){
    return std::strerror(error_num);
}

【讨论】:

    【解决方案2】:

    除了 François 的回答,让我们看看使用 GCC 的 Linux 系统上的预处理器输出是什么。 g++ -E test.cpp 给:

    # 6 "test.cpp"
    std::string errorString(int 
    # 6 "test.cpp" 3 4
                               (*__errno_location ())
    # 6 "test.cpp"
                                    ){
        return std::strerror(
    # 7 "test.cpp" 3 4
                            (*__errno_location ())
    # 7 "test.cpp"
                                 );
    }
    

    所以errno 在这里定义为(*__errno_location ())。其实是一个函数调用,但是如果你把int放在前面,也正好是一个合法的参数声明。

    欢迎宏。

    【讨论】:

    • 期待这个,htons 和所有其他宏都会被替换!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    相关资源
    最近更新 更多