GCC 11.1 终于在昨天发布了。但是,现在它只能从源代码构建,所以我想知道我们什么时候可以使用它apt?
我最近一直在尝试使用 GCC 11 将代码库转换为 C++20 模块。但是,我遇到了以下情况。首先,这是使用标头完成的方法:
\n啊
\nclass B;\n\nclass A {\n public:\n void f(B& b);\n};\nRun Code Online (Sandbox Code Playgroud)\na.cpp
\n#include "A.h"\n#include "B.h"\n\nvoid A::f(B& b)\n{\n // do stuff with b\n}\nRun Code Online (Sandbox Code Playgroud)\n(Bh的内容在这里并不重要)
\n需要注意的是 B 的前向声明。并不是每个使用 A 的人都应该关心 B,所以我使用前向声明来阻止重新编译的发生。有了标题,这种情况就完美了。
\n问题在于尝试将此代码转换为模块时。主要问题是实体与声明它们的模块相关联,因此在 Ah 中向前声明是不可能的。我尝试在全局模块中进行前向声明,但编译器仍然抱怨 B 的定义与其声明位于不同的模块中。我还尝试使用第三个模块,其中仅包含 B 的前向声明,但这仍然是在两个不同的模块中声明和定义 B。所以,我的主要问题是:如何从模块外部转发声明某些内容? 我也会对最终产生相同效果的方式感到满意:当 B 更改时,A 的用户不需要重新编译。
\n在搜索时,我发现了一些地方谈论类似的情况,但由于某种原因它们都不起作用。他们不起作用的原因:
\n编辑:为了回应评论,以下是我尝试过的一些事情的详细信息:
\n尝试 1:在 A.mpp 中转发声明 …
struct details_state {
struct details_status D1;
struct details_status D2;
};
struct details {
struct details_state details_states[2];
} __attribute__((packed));
struct details *p;
void print_details_status(struct details_status *s)
print_details_status(&(p->details_states[i].D1));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
警告:获取“结构详细信息”的打包成员的地址可能会导致未对齐的指针值 [-Waddress-of-packed-member]
GCC 在 >9 版本中给出此警告。如何在不使用 [-Wno-address-of-packed-member] 的情况下摆脱此警告
OpenMP 规范从 5.0 版开始定义了OMPT接口,以允许外部工具查询 openmp 运行时。
我想尝试一下,但我真的很困惑主流编译器实际上如何支持这一点。
GCC-11 声称扩展了对 openmp 5.0 的支持,但关于 OMPT,我找不到相应的ompt.h头文件(在我的例子中,Ubuntu 包libgcc-11-dev提供了omp.h)。
clang-12 确实提供了ompt.h(package ),但是示例程序libomp-12-dev的编译失败,第一个错误是,并且实际上在.unknown type name 'ompt_invoker_t'ompt.h
我不清楚目前的支持状况。我找不到 GCC 的准确状态,而 clang 提供了此信息https://clang.llvm.org/docs/OpenMPSupport.html,从中我无法弄清楚大部分完成的背后是什么。
谁能帮我找到最新信息或任何有关此的提示?
我发现了一种似乎完全没问题的特定使用模式,并且以前没有编译器抱怨过。现在它对 gcc-11 发出警告:下面是一个接近最小的示例。另存为t.c并使用 进行编译gcc-11 -O2 -Wall -c t.c。
#include <stdlib.h>\n#include <string.h>\n\nextern void f(const char *s);\n\nvoid\nt(int len, char *d)\n{ char tmp[500];\n char *s, *o;\n int i;\n\n if ( len <= sizeof(tmp) )\n s = tmp;\n else if ( !(s=malloc(len)) )\n return;\n\n for(o=s,i=0; i < len; i++)\n *o++ = d[i]+1;\n\n f(s);\n// i = strlen(s);\n if ( s != tmp )\n free(s);\n}\n\nRun Code Online (Sandbox Code Playgroud)\n编译结果为:
\ngcc-11 -O2 -Wall -c t.c\nt.c: In function \xe2\x80\x98t\xe2\x80\x99:\nt.c:20:3: warning: \xe2\x80\x98s\xe2\x80\x99 may be used …Run Code Online (Sandbox Code Playgroud) 我在我的机器(linux 20.04)上使用自制软件安装了 gcc 11。而且它没有在 vscode 上运行,如图所示
as:无法识别的选项“--gdwarf-5”
不知道是不是路径问题。因为当我安装brew时它告诉我
Warning: /home/linuxbrew/.linuxbrew/bin/ is not in your PATH.
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,它建议使用这三个命令
echo '# Set PATH, MANPATH, etc., for Homebrew.' >> /home/hasib/.profile
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/hasib/.profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
Run Code Online (Sandbox Code Playgroud)
所以,我做了那些。我不知道这是否搞砸了路径。我对Linux有点陌生,所以很困惑。只是想在 vs 上运行 gcc-11
这是我的tasks.json 文件:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": …Run Code Online (Sandbox Code Playgroud) 这可能不是 C++20 特有的,但这就是我现在正在使用的。我有一个简单的结构
\nstruct foo {\n int bar;\n}\nRun Code Online (Sandbox Code Playgroud)\n可以声明并初始化为
\nconst auto baz = foo{42};\nRun Code Online (Sandbox Code Playgroud)\n现在,当我禁用移动构造函数 ( foo(foo&&) = delete;) 时,上述初始化失败并显示
\n\n错误:没有匹配的函数可调用 \xe2\x80\x98foo::foo()\xe2\x80\x99
\n
出现此错误的原因是什么?有没有办法恢复默认行为?
\n