问题标签 [gcc7]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - GCC 7,aligned_storage 和“取消引用类型双关指针将破坏严格别名规则”
我编写的代码在 GCC 4.9、GCC 5 和 GCC 6 中没有警告。在一些较旧的 GCC 7 实验快照(例如 7-20170409)中也没有警告。但在最近的快照中(包括第一个 RC),它开始产生关于混叠的警告。代码基本上归结为:
使用最新的 GCC 7 RC 编译:
(有趣的观察是禁用优化时不会产生警告)
使用 GCC 6 编译完全没有警告。
现在我想知道,上面的代码肯定有类型双关语,对此毫无疑问,但不std::aligned_storage
应该这样使用吗?
例如,此处给出的示例代码通常不会对 GCC 7 产生警告,但这仅仅是因为:
std::string
不知何故不受影响,std::aligned_storage
使用偏移量访问。
通过更改std::string
为int
,删除偏移访问std::aligned_storage
和删除不相关的部分,你会得到:
这会产生完全相同的警告:
所以我的问题是 - 这是一个错误还是一个功能?
c++ - 一些模板函数不再在 gcc 7 中编译
从 gcc 6.1 升级到 7.1 后,我的一些代码不再编译:
我在使用模板函数的各种类中遇到了大约 20 个这样的错误。在这种情况下vector2
是一个简单的模板类,定义为:
是的cast
成员函数vector2
,定义为:
坦率地说,我在这里看不到问题,错误消息也没有指出任何明显的问题。任何想法为什么这突然失败?
c++ - 为什么包括打破 GCC 中的结构化绑定?
考虑:
此代码在 C++17 模式下使用 gcc 7.1 编译得很好,但是这个:
给出一个错误:
这里发生了什么?编译器错误,或者这是结构化绑定应该如何工作?
c++ - std::unordered_map::merge() 的安全性
在编写一些针对 C++17 的代码时,我遇到了一个绊脚石,用于确定合并两个兼容的 std::unordered_maps 的操作的异常安全性。根据当前的工作草案第 26.2.7 节,表 91 部分内容涉及以下条件a.merge( a2 )
:
要求:
a.get_allocator() == a2.get_allocator()
。尝试使用 的散列函数和键相等谓词提取每个元素
a2
并将其插入。在具有唯一键的容器中,如果某个元素的键与来自 的元素的键等效,则不会从 中提取该元素。a
a
a
a2
a2
后置条件:指向被转移元素的指针和引用
a2
指代那些相同的元素,但作为a
. 引用被转移元素的迭代器和所有引用的迭代器a
都将失效,但剩余元素的迭代器a2
将保持有效。抛出:除非散列函数或键相等谓词抛出,否则什么都没有。
值得注意的是,这些条件强烈地让人想起那些在 §26.2.6 表 90 中给出的普通关联容器 (std::map) 的要求a.merge( a2 )
:
要求:
a.get_allocator() == a2.get_allocator()
。尝试使用 的比较对象提取其中的每个元素
a2
并将其插入。在具有唯一键的容器中,如果某个元素的键与来自 的元素的键等效,则不会从 中提取该元素。a
a
a
a2
a2
后置条件:指向被转移元素的指针和引用
a2
指代那些相同的元素,但作为a
. 引用被转移元素的迭代器将继续引用它们的元素,但它们现在表现为迭代器 intoa
,而不是 intoa2
。抛出:除非比较对象抛出,否则什么都没有。
我需要合并两个具有相同数量元素的 std::unordered_maps,我可以确保这在两个容器中都是唯一的,这意味着包含合并结果的地图的元素数量将是以前的两倍,并且容器合并- from 将是空的。多亏了 C++17,这应该是完全安全的,对吧?
就性能而言,这是一个巨大的胜利……除了,我有这个挥之不去的疑问。有趣的是,后置条件语句没有说明合并映射中的前一个最大负载因子是否会得到尊重,虽然这似乎是一个安全的隐含假设,但它似乎与关于 unordered_map 异常安全性的语句发生了天真的冲突。如果您使用哈希表设计,其中存储桶是连续分配的缓冲区,那么保持负载因子似乎意味着重新散列,这似乎意味着重新分配存储桶缓冲区。
这似乎已经是一种极端的凝视练习,并且有充分的理由不理会它:可以想象,可以将更复杂的哈希表制作为完全基于节点的结构,类似于通常支撑 std 的红黑树::map,在这种情况下,规范似乎是合理的,因为重新散列并不意味着分配。
也许对我有利的是,我屈服于怀疑并深入研究了 gcc-7.1 的合并实现。这非常复杂,但总结一下我的发现,我发现存储桶确实是连续分配的缓冲区,并且重新散列确实意味着重新分配。也许,我想,我错过了一些更深层次的魔法(我盯着源代码看了将近一整天,仍然觉得我对它的理解很差)它只是在合并期间禁用了重新散列,这意味着所有指定的条件会得到支持,但在适当大的合并后你可能会得到一个令人讨厌的性能回归,因为你的地图可能会超载。
我进行了反映我的用例的实际评估(如果可能的话,我会提出,对不起),而不是仅仅质疑我对 libstdc++ 的解释:
果然,在GCC-7.1下编译这段代码后,我得到:
然而,取消注释第 95 行 ( m1.reserve( m1.size() + m2.size() );
) 会产生预期的输出:
了解 C++17 仍然是一个尚未最终确定的标准草案,并且 gcc 的实现是实验性的,我想我的问题是:
- 我是否严重误解了标准中规定的合并操作的安全性?是否有使用
std::unordered_map::merge()
我错过的最佳实践?我是否应该暗中负责确保桶的分配?std::unordered_map::reserve()
当 clang、MSVC 和 Intel 最终支持 C++17 时,使用实际上是可移植的吗?我的意思是,当无法进行无异常合并时,我的程序中止确实遵循列出的后置条件……</li> - 这实际上是标准中的缺陷吗?如果文本被复制粘贴,无序关联容器和普通关联容器之间措辞的相似性可能会导致意外的保证。
- 这只是一个 gcc 错误吗?
值得注意的是,在撰写本文之前,我确实检查了 gcc 的错误跟踪器,似乎没有发现与我的描述相匹配的开放错误,此外,我检查了 C++ 标准缺陷报告,同样似乎是空的(诚然,做了一个该网站的文本搜索正在加重,我可能不够彻底)。后者并不令人惊讶,因为标准缺陷及其解决方法或后果通常会在 gcc 的源代码中注明,而我在检查期间没有发现这样的符号。我尝试在最近的 clang 签出(超过一周)中编译我的示例代码,但是编译器出现了段错误,所以我没有进一步检查,也没有咨询 libc++。
undefined-reference - 在 Arch Linux 上构建微软 CNTK 时出错:libCntk.Eval-2.0.so 抱怨未定义对 TensorView 的引用
我正在尝试CNTK
从源代码构建Arch Linux
。
git 命令:
配置和制作命令:
错误:
TensorView
是一部分Source/Math
,所以我期待libCntk.Math-2.0.so
。但在错误消息中,libCntk.Eval-2.0.so
抱怨未定义对TensorView
.
谢谢!
编辑1:
所有三个 .so 文件均已构建且可用:
编辑2:
mpic++ --version
给g++ (GCC) 7.1.1
作者建议使用gcc 4.8
. 但是,我不想gcc
在机器上有两个版本。
编辑3:
根据我从作者那里得到的建议(https://github.com/Microsoft/CNTK/issues/2025),我EVAL_CLIENT
在Makefile
. 但是,错误移至以下目标Makefile
:CNTKLIBRARY_CPP_EVAL_EXAMPLES
编辑4:
似乎该错误与链接器和一些标志有关,例如--as-needed
,--whole-archive
等。但是,我还无法修复它。
谢谢!
c++ - libstdc++ 静态链接和 System V ABI
当我使用 编译时-static-libstdc++
,编译后的二进制文件使用UNIX - GNU
ABI,但我需要使用 ABI 获取二进制文件UNIX - System V
。(我需要与 FreeBSD 兼容)我还尝试了 Compile libstdc++ with hash style SYSV,但它没有帮助。
version - Fedora 26 dumpversion 上的 gcc 7.1.1 现在默认只包含主要版本
从 Fedora 25 升级到 26 后,默认的 gcc 版本现在是 7.1.1 版本,并且输出gcc -dumpversion
已从 major.minor.patch 更改为仅 major。
新输出:
手册指出
-转储版本
打印编译器版本(例如,3.0、6.3.0 或 7)——不要做任何其他事情。这是文件系统路径、规范中使用的编译器版本,可能取决于编译器的配置方式,只有一个数字(主要版本)、两个由点分隔的数字(主要和次要版本)或三个由点分隔的数字(主要版本) 、次要版本和补丁级别版本)。
我还没有找到在哪里更改此编译器配置以包含用点配置的三个数字。我发现的最接近的是仅主要版本的配置:
--with-gcc-major-version-only 指定 GCC 在文件系统路径中应该只使用主编号而不是 major.minor.patchlevel。
c++ - 使用 std::addressof 时出现 GCC 7 编译错误
我正在观察一些我无法完全解释的奇怪行为。代码如下所示:
这是一个与https://godbolt.org/g/YcNdbf一起玩的版本 问题是这段代码使用 gcc4.9-6.3 编译得很好,但在 gcc 7.1 下失败。Clang 也不喜欢它。
(编辑)来自 gcc 7.1 的错误消息:
但是,我不太明白为什么它不起作用。
在此先感谢任何试图提供帮助的人:)
c++ - gcc 7.2 上的非虚拟 thunk 有时太大
我尝试从 gcc 4.9 (gcc-arm-none-eabi, -O2) 迁移到 gcc 7.2。我的代码构建成功,但结果程序比 gcc 4.9 上的要大。
我做了一些调查并意识到,如果在类中定义了覆盖函数,那么“xxx 上的非虚拟 thunk”的大小太大了:
可能有一个选项可以防止这种内联?
linux - 将 gcc 7.2 从 x86_64 交叉编译到 aarch64
我已经成功地从 x86_64 上的源代码编译了 gcc 7.2。本机到本机,因此生成的编译器是一个可以正常工作的 x86_64 二进制文件。
我还想有一个适用于 aarch64 的编译器(所以,不是交叉编译器。产生 aarch64 结果的 aarch64 编译器二进制文件。)这就是我卡住的地方。
有两个选项,在 aarch64 主机上对 gcc 进行本机到本机编译。这会导致问题,而且最重要的是,像软糖一样慢,或者在 x86_64 上交叉编译 gcc,导致 aarch64 编译器二进制文件能够生成其他 aarch64 二进制文件。
我下载并解压了 gcc 7.2,并做了这download_prerequisites
一步。然后我使用了以下内容configure
:
不过,我怀疑--build
,--host
并且--target
在本地情况下是矫枉过正的。我现在的问题是,如果我想最终使用 aarch64 编译器,我应该将这三个设置为什么?
下线,我还想要一个 armv7l 版本。有什么选择呢?