gpt4 book ai didi

c++ - 关于 WEXITSTATUS 与 `G++ 4.9.4` 的奇怪行为

转载 作者:行者123 更新时间:2023-12-05 04:29:17 25 4
gpt4 key购买 nike

下面的代码片段可以编译,

#include<sys/types.h>
#include<sys/wait.h>
#include<iostream>

int main()
{
int ret = 0xFFFF;
std::cout << WEXITSTATUS(ret);
}

而此代码片段确实无法使用 G++ 4.9.4 进行编译:

#include<sys/types.h>
#include<sys/wait.h>
#include<iostream>

int main()
{
std::cout << WEXITSTATUS(0xFFFF);
}

这是编译器提示的内容:

In file included from /usr/include/x86_64-linux-gnu/sys/wait.h:77:0,
from t.cpp:2:
t.cpp: In function ‘int main()’:
t.cpp:7:22: error: lvalue required as unary ‘&’ operand
std::cout << WEXITSTATUS(0xFFFF);
^

这里是关于编译器的详细信息:

g++ --version
g++ (Ubuntu 4.9.4-2ubuntu1~16.04) 4.9.4
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

并通过以下命令在Ubuntu16.04上安装编译器

sudo apt-get install gcc-4.9
sudo apt-get install g++-4.9
sudo update-alterntives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 20
sudo update-alterntives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 20

注意:我必须使用 g++-4.9,我别无选择。

奇怪的是,我无法在 godbolt.org 上重现上述现象。它compiles on godbolt.org使用 gcc 4.9.3(gcc 4.9.4 不可用)。

这是 g++ -E the_said_code_snippet_does_not_compile.cpp 的输出

//omit
# 4 "t.cpp" 2

int main()
{
std::cout << ((((*(const int *) &(0xFFFF))) & 0xff00) >> 8);
}

谁能解释一下这个问题?

已更新:

我现在可以重现错误!查看此 link .

已更新:

这只是一个简化的例子。我实际面临的是 WEXITSTATUS(pclose(fp)) 无法编译。

最佳答案

WEXITSTATUS 宏是 C 标准库实现的问题,而不是编译器本身的问题。通常(在 GCC 的情况下)编译器不提供 C 标准库实现。它是一个独立的包。

大多数 Linux 发行版,包括 Ubuntu,都使用 glibc 作为 C 标准库实现。

在 2.23 版之前的 glibc 中,当使用 C++ 和 __USE_MISC 时,宏是按以下方式定义的已设置(请参阅下面的提交链接):

#   define __WAIT_INT(status)   (*(const int *) &(status))

// ...

# define WEXITSTATUS(status) __WEXITSTATUS (__WAIT_INT (status))

宏的实际实现在__WEXITSTATUS里面,但是使用__WAIT_INT似乎是为了支持非POSIX的“ union 等待” "wait 接口(interface)的变体。根据这个定义,纯右值不能与宏一起使用,因为它试图获取 status 的地址。

2016 年,commit b49ab5f4503f36dcbf43f821f817da66b2931fe6union wait 的支持 - 根据 1990 年代初期弃用的 NEWS 条目 - 已被删除,现在的定义很简单

# define WEXITSTATUS(status)    __WEXITSTATUS (status)

现在它也适用于纯右值。

似乎 Ubuntu 16.04 仍然使用该更改之前的 glibc 版本,这并不奇怪,因为它是在提交时发布的。

我不知道 POSIX 怎么说是否可以将宏与 int 右值而不是变量名一起使用。

WEXITSTATUS 不能总是直接用于调用 pclose 似乎是已知问题。显然,上面提到的扩展,现在不再出现在 glibc 中,曾经(现在?)也出现在(某些?)BSD 中(并且可能源自它们?)。参见例如this question ,其中的答案也表达了对 POSIX 合规性的怀疑。但是,链接问题中提到的 OpenBSD 也在 2014 年删除了 union wait。根据 changelog自 4.3BSD(1986 年发布)以来,它已被弃用。

关于c++ - 关于 WEXITSTATUS 与 `G++ 4.9.4` 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72387774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com