Questions tagged «gcc»

GCC是GNU编译器集合。它是Linux上针对C,C ++,Go,Fortran和Ada的事实上的标准编译器,并且还支持许多其他语言和平台。除编译器外,GCC还具有一个工具链(libc,libstdc ++,objdump,nm等),该工具链已在多个平台和系统上广泛使用。

1
为什么GCC不能假设std :: vector :: size在此循环中不会改变?
我要求一个if (i < input.size() - 1) print(0);在此循环中得到优化的同事,这样input.size()就不会在每次迭代中都读取它,但事实证明并非如此! void print(int x) { std::cout << x << std::endl; } void print_list(const std::vector<int>& input) { int i = 0; for (size_t i = 0; i < input.size(); i++) { print(input[i]); if (i < input.size() - 1) print(0); } } 根据带有gcc选项的Compiler Explorer,-O3 -fno-exceptions我们实际上是在读取input.size()每个迭代并lea用于执行减法运算! movq …
14 c++  gcc  assembly 

5
比较一下布尔值
假设我有一组以uint16_t编码的标志flags。例如,AMAZING_FLAG = 0x02。现在,我有一个功能。此函数需要检查是否要更改标志,因为如果要更改标志,则需要写入闪存。那很贵。因此,我想要一张支票告诉我是否flags & AMAZING_FLAG等于doSet。这是第一个想法: setAmazingFlag(bool doSet) { if ((flags & AMAZING_FLAG) != (doSet ? AMAZING_FLAG : 0)) { // Really expensive thing // Update flags } } 这不是直观的if语句。我觉得应该有更好的方法,例如: if ((flags & AMAZING_FLAG) != doSet){ } 但这实际上不起作用,true似乎等于0x01。 因此,有没有一种比较布尔值的好方法?

1
为什么用g ++编译该代码会花费这么长时间?
考虑以下代码: template<int i> class A { typedef A<i-1> B; B x, y; }; template<> class A<0> { char m; }; int main() { A<LEVEL> a; } 通过以下Bash命令(使用g ++ 8.3.0)对g ++编译进行基准测试时 for ((level=1; level<30; ++level)); do echo -n ${level}, /usr/bin/time -f %U g++ -DLEVEL=$level test.cpp -o /dev/null done 我得到以下输出: 1,0.03 2,0.03 …

4
是否有一个C代码片段,可以在不使用编译器内置函数的情况下有效地计算溢出安全加法?
这是一个C函数,将C添加int到另一个函数,如果发生溢出将失败: int safe_add(int *value, int delta) { if (*value >= 0) { if (delta > INT_MAX - *value) { return -1; } } else { if (delta < INT_MIN - *value) { return -1; } } *value += delta; return 0; } 不幸的是,GCC或Clang 无法对其进行优化: safe_add(int*, int): movl (%rdi), %eax testl …

2
IBM示例代码,不可重入函数在我的系统中不起作用
我正在研究编程的重入性。在IBM的这个站点上(确实不错)。我建立了一个代码,复制到下面。这是在网站上滚动的第一个代码。 该代码尝试通过打印在“危险上下文”中不断变化的两个值来显示涉及在文本程序的非线性开发中共享访问变量的问题(异步性)。 #include <signal.h> #include <stdio.h> struct two_int { int a, b; } data; void signal_handler(int signum){ printf ("%d, %d\n", data.a, data.b); alarm (1); } int main (void){ static struct two_int zeros = { 0, 0 }, ones = { 1, 1 }; signal (SIGALRM, signal_handler); data = zeros; alarm …
11 c  gcc  signals  x86-64  data-race 

1
GCC实施的尖括号包含。为什么必须如下所述?
本文档在其2.6计算的包括部分中具有以下段落: 如果该行扩展到以<令牌开头并包括>令牌的令牌流,则<和第一个>之间的令牌将合并以形成要包含的文件名。令牌之间的任何空格都减少为一个空格;那么将保留初始<之后的任何空格,但忽略闭合>之前的结尾空格。CPP根据尖括号包含的规则搜索文件。 我知道这是实现定义的,但是为什么GCC必须采用这种方式?我指的是上面突出显示的句子。 编辑 我刚刚注意到,上面引用的第三段之前的内容如下: 定义宏时必须小心。#define保存令牌,而不是文本。预处理器无法知道该宏将用作的参数#include,因此它会生成普通标记,而不是标头名称。如果您使用的双引号包含与字符串常量足够接近,则这不太可能引起问题。 但是,如果使用尖括号,则可能会遇到麻烦。 有谁知道这里指出了什么麻烦?
10 c++  c  gcc  language-lawyer 

1
为何编译器坚持在此处使用被调用者保存的寄存器?
考虑下面的C代码: void foo(void); long bar(long x) { foo(); return x; } 当我在GCC 9.3上使用-O3或编译它时-Os,得到以下信息: bar: push r12 mov r12, rdi call foo mov rax, r12 pop r12 ret clang的输出是相同的,除了选择rbx而不是r12作为被调用者保存的寄存器。 但是,我希望/希望看到看起来像这样的程序集: bar: push rdi call foo pop rax ret 用英语,这就是我所看到的: 将已保存被调用者的寄存器的旧值推入堆栈 移动x到该被调用方保存寄存器 呼叫 foo 移动x从被调用者被保存的寄存器到返回值寄存器 弹出堆栈以恢复被调用方保存的寄存器的旧值 为什么要弄乱所有保存在被调用方中的寄存器?为什么不这样做呢?它看起来更短,更简单,并且可能更快: 推x入栈 呼叫 foo x从堆栈弹出到返回值寄存器 我的大会错了吗?它比以多余的寄存器搞乱效率低吗?如果对这两个问题的回答都是“否”,那么为什么GCC或clang都不这样做呢? …
10 c  gcc  assembly  clang  x86-64 

3
可以将nullptr转换为uintptr_t吗?不同的编译器不同意
考虑以下程序: #include <cstdint> using my_time_t = uintptr_t; int main() { const my_time_t t = my_time_t(nullptr); } 无法使用msvc v19.24进行编译: <source>(5): error C2440: '<function-style-cast>': cannot convert from 'nullptr' to 'my_time_t' <source>(5): note: A native nullptr can only be converted to bool or, using reinterpret_cast, to an integral type <source>(5): error C2789: 't': …
10 c++  c++11  gcc  visual-c++  clang 

1
GCC / C ++ 17中带有模板模板类的问题
考虑以下2个重载 template<typename T> bool test() { return true; } template<template<typename ...> class T> bool test() { return false; } 第一个适用于常规类,而第二个适用于未实例化的模板。例如: std::cout<<test<int>()<<std::endl; <-- this yields 1 std::cout<<test<std::list>()<<std::endl; <--this yields 0 现在考虑以下模板函数: template<typename U> bool templfun(){ struct A{ bool f(){ return test<A>(); // <-- this gives an error } }; return test<A>(); …
10 c++  templates  gcc  clang  c++17 

1
在使用GCC的unordered_map :: insert KeyEqual异常期间发生内存泄漏-破坏了强有力的异常安全保证吗?
我正在使用GCC 7.3.1,但也在coliru(我相信它是9.2.0版)上进行了测试。使用以下内容进行构建: g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp 这里是rai.cpp: #include <iostream> #include <unordered_map> int main() { try { struct MyComp { bool operator()(const std::string&, const std::string&) const { throw std::runtime_error("Nonono"); } }; std::unordered_map<std::string, std::string, std::hash<std::string>, MyComp> mymap; mymap.insert(std::make_pair("Hello", "There")); mymap.insert(std::make_pair("Hello", "There")); // Hash match forces compare } catch (const std::exception& e) { …

2
不同C ++编译器之间的自动类型推导不匹配
因此,我试图以某种现代C ++的形式实现点积(https://en.wikipedia.org/wiki/Dot_product),并提出了以下代码: #include <iostream> template<class... Args> auto dot(Args... args) { auto a = [args...](Args...) { return [=](auto... brgs) { static_assert(sizeof...(args) == sizeof...(brgs)); auto v1 = {args...}, i1 = v1.begin(); auto v2 = {brgs...}, i2 = v2.begin(); typename std::common_type<Args...>::type s = 0; while( i1 != v1.end() && i2!= v2.end()) { s …


1
CHAR_WIDTH未声明
‘CHAR_WIDTH’ undeclared 尝试编译此简单程序时出现错误 : #include <stdio.h> #include <limits.h> int main() { printf("CHAR_BIT = %d\n", CHAR_BIT); printf("CHAR_WIDTH = %d\n", CHAR_WIDTH); return (0); } 与 gcc ./show_char_width.c -o show_char_width 和gcc:由GNU C版本8.3.0,GMP版本6.1.2,MPFR版本4.0.2,MPC版本1.1.0编译的GNU C17(Ubuntu 8.3.0-6ubuntu1)版本8.3.0(x86_64-linux-gnu) ,isl版本isl-0.20-GMP,内核:5.0.0-37-generic。 如此处所述, CHAR_WIDTH应该在我的程序中包含的limits.h中定义。那么为什么我会收到此错误? 使用该-v选项,我发现将在这些目录中搜索该库: #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/8/include /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed /usr/include/x86_64-linux-gnu /usr/include …
9 c  gcc 

4
为什么C编译器会优化开关,以及是否有所不同
当我偶然发现一个奇怪的问题时,我正在从事一个个人项目。 在一个非常紧密的循环中,我有一个整数,其值在0到15之间。对于值0、1、8和9,我需要获取-1,对于值4、5、12和13,我需要获取1。 我转向godbolt检查一些选项,并惊讶于编译器似乎无法以与if链相同的方式优化switch语句。 链接在这里:https : //godbolt.org/z/WYVBFl 代码是: const int lookup[16] = {-1, -1, 0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1, 0, 0}; int a(int num) { return lookup[num & 0xF]; } int b(int num) { num &= 0xF; if (num == 0 || num == …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.