发呆是什么意思| 胆经不通吃什么中成药| 下头是什么意思| 花字五行属什么| 为什么医生不推荐特立帕肽呢| 生长激素由什么分泌| 办结婚证需要什么| 抽烟有什么危害| 在眼皮老跳是什么征兆| 不想吃饭没胃口是什么原因| 什么什么不得| 杨少华什么辈分| 甲醛中毒挂什么科| 母亲节可以做什么礼物| 漫山遍野是什么意思| 尿液带血什么原因| 蒸鱼豉油可以用什么代替| 不利是什么意思| 附睾炎是什么原因引起的| 宫颈炎盆腔炎吃什么药效果最好| 手指麻木吃什么药| 服役是什么意思| 仙居杨梅什么时候上市| 尿偏红色是什么原因| 鲁迅是什么样的人| 破伤风是什么| 阿斯伯格综合症是什么| 班禅是什么级别| 68岁属什么| 耽美什么意思| 什么是真菌感染| 什么叫肠化生| 什么叫高潮| ny是什么牌子| 凌晨3点多是什么时辰| 尿痛流脓吃什么药| 菠菜补什么| 心跳过快是什么原因| 舌头麻是什么原因| bkg是什么意思| 什么是猝死| 蜻蜓吃什么| 就请你给我多一点点时间是什么歌| 吃蝎子有什么好处| 什么是黑科技| 外阴瘙痒用什么药| 9.27日是什么星座| 大便带油花是什么原因| 臭虫怕什么东西| 配菜是什么意思| 为什么手会掉皮| 为什么左眼皮一直跳| 前列腺增生有什么危害| eb是什么| 凯旋归来是什么意思| 处女膜破了有什么影响| 拔罐后需要注意什么| 嗯嗯嗯是什么意思| 仙女座是什么星座| 吃什么对肝脏好| 怀姜是什么姜| 黄瓜可以和什么一起榨汁| 弼马温是什么意思| 明油是什么油| 助产学出来是干什么的| 格桑花的花语是什么| 2022年是什么生肖年| 舌苔发黑是什么病的前兆| 肺部拍片挂什么科| 八月初六是什么星座| 波澜壮阔是什么意思| 有白痰是什么原因| 西瓜不可以和什么同食| 肠痈是什么病| 雾化治疗的作用是什么| 什么洗面奶最好用排行第一| 河堤是什么意思| 装修属于什么行业| 斛是什么意思| 贪心不足蛇吞象什么意思| 戒烟有什么方法| 萘普生是什么药| 发烧看什么科| 脊柱侧弯挂什么科| 女人更年期是什么症状| 肌酐高吃什么食物好| 小便有点刺痛是什么原因引起的| 腱鞘炎是什么原因引起的| 白细胞少什么原因| 上天是什么意思| 什么是共产主义社会| 意犹未尽什么意思| 免疫球蛋白低说明什么| 什么叫支原体阳性| 什么降糖药效果最好| 涟漪什么意思| 1月9号是什么星座| 男人脚肿是什么病的前兆| 飞水是什么意思| 憨憨是什么意思| DDP是什么| ada是什么意思| 牛奶为什么能解辣| 西洋参跟花旗参有什么区别| 土笋冻是什么虫子| 久坐伤什么| 嘴巴长溃疡是什么原因| 老戏骨是什么意思| 情何以堪是什么意思| 敲木鱼是什么意思| 吃什么药可以提高性功能| 静怡是什么意思| 唯粉是什么意思| 长痱子是什么原因| 唐老鸭叫什么名字| 宫外孕是什么导致的| 乙肝五项一五阳性什么意思| 氨纶是什么面料优缺点| 胸部ct平扫能检查出什么| 吃什么去湿气最好最快| 流产会出现什么症状| 九牛一毛是什么生肖| 蜱虫用什么药可以消灭| 狗狗流鼻涕吃什么药| bur什么意思| 肉桂有什么作用| 冲猴煞北是什么意思| 福肖指什么生肖| 湿气重吃什么中药| 两个方一个土是什么字| 什么都| 梦见买衣服是什么意思| 人生格言是什么意思| 塔罗是什么| 1970年属什么生肖| 宅基地是什么意思| 专情是什么意思| 黑豆腐是什么做的| 脸部神经跳动吃什么药| 鸦雀无声是什么意思| 宗人府是什么地方| ft是什么| 黄疸高吃什么药| 伺候是什么意思| 3.8号是什么星座| 流清水鼻涕吃什么药| 一什么羊| 补睾丸吃什么药最好| 纳氏囊肿是什么意思| anca医学上是什么意思| 空腹是什么意思| 可乐杀精是什么意思| 有福是什么意思| ch是什么意思| 1992年五行属什么| 斯德哥尔摩是什么意思| 吊人什么意思| 几何图形是什么| 血压高吃什么药| 手背发麻是什么原因| 野是什么意思| 菊花不能和什么一起吃| 快闪是什么意思| 输卵管堵塞什么症状| 忠心不二是什么生肖| 痦子和痣有什么区别| 子宫形态失常是什么意思| 右手发麻是什么病的前兆| 脂溢性皮炎是什么引起的| 医疗保险是什么| 脚气涂什么药膏| 树根有什么作用| 轴向是什么意思| 尿比重偏低是什么原因| 冬眠灵是什么药| 五味子是什么味道| 井盖为什么是圆的| 载脂蛋白a偏高是什么意思| 不停的放屁是什么原因| 脾胃虚吃什么| 项链突然断了预示什么| 宫颈糜烂用什么药最好| 斯凯奇鞋是什么档次| 地笼捕河虾用什么诱饵| 手指长倒刺是什么原因| 皮肤一碰就破是什么病| 北极熊为什么不怕冷| 睾丸小是什么原因| 痿是什么意思| 咖啡过敏的症状是什么| 为什么现在不建议输液| 前列腺炎是什么意思| 酸碱度是什么意思| 背锅侠是什么意思| 降钙素原高是什么原因| 不显山不露水是什么意思| 什么是红眼病| 市局长是什么级别| mhc是什么意思| 属马的人佩戴什么招财| 女性排卵期出血是什么原因| 甲功五项能查出什么病| 腿脚发麻是什么原因| 小孩腰疼是什么原因| 帝王蟹什么季节吃最好| 嗜碱性粒细胞偏低说明什么| 子宫内膜增厚是什么原因| 乳头状瘤是什么病| 眼底出血是什么原因| foreverlove是什么意思| 动脉抽血是做什么检查| 吃什么下奶最快最多最有效| 刻舟求剑的意思是什么| 什么样的男人值得托付终身| 说什么情深似海我却不敢当| 教师节应该送老师什么花| 脑梗病人吃什么营养恢复最好| 梦到和老公吵架是什么意思| 酒酿蛋什么时候吃效果最好| 大姨妈来了吃什么| 潜行是什么意思| 旅长是什么级别| 输卵管囊肿是什么原因引起的| 一感冒就咳嗽是什么原因| 天热头疼吃什么药| 事无巨细是什么意思| 主见是什么意思| 新斯的明是什么药| 医生说忌生冷是指什么| 胎记是什么| 金字旁的有什么字| hp是阳性什么意思| 印度人为什么叫阿三| 胆码是什么意思| 月柱金舆是什么意思| 脖子上长癣是什么原因| 乙肝病毒表面抗体高是什么意思| 宫颈纳氏囊肿什么意思| 筋膜炎吃什么药好| 什么是果糖| 内火旺是什么原因| 什么都不需要| 暴露是什么意思| 为什么会牙疼| 身份证有x代表什么| 胎儿脐带绕颈是什么原因造成的| 车前草的作用是什么| 乳酸是什么| 火龙果吃了有什么好处| 一什么眼镜| 面部神经挂什么科| 跳蚤的天敌是什么| 龙虎山是什么地貌| 秦始皇叫什么名字| 唇炎属于什么科| 有点想吐是什么原因| gtp是什么| 剖腹产吃什么下奶最快| 火把节是什么节日| 肾积水吃什么药最好| 脑梗的人适合吃什么食物| 闰月给父母买什么| 多吃木瓜有什么好处| 晚上睡眠不好有什么办法可以解决| 百度 Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

April 10, 2025
David Malcolm
Related topics:
C, C#, C++CompilersLinuxSecure Coding
Related products:
Red Hat Enterprise Linux

Share:

    百度 “针尖大的窟窿能透过斗大的风”,一个人一旦处事不慎、心态不好、自律不严,就会越走越偏,最终导致小事变大事、小错酿大祸。

    I work at Red Hat on GCC, the GNU Compiler Collection. I spent most of the past year working on how GCC emits diagnostics (errors and warnings) in the hope of making it easier to use. Let's take a look at 6 improvements to look forward to in the upcoming GCC 15.

    1. Prettier execution paths

    I added a static analyzer to GCC in GCC 10 that prints visualizations of predicted paths of execution through the user's code, demonstrating each problem it predicts.

    Here's an example that shows some of the improvements I've made to this in GCC 15:

    infinite-loop-linked-list.c: In function ‘while_loop_missing_next’:
    infinite-loop-linked-list.c:30:10: warning: infinite loop [CWE-835] [-Wanalyzer-infinite-loop]
       30 |   while (n)
          |          ^
      ‘while_loop_missing_next’: events 1-3
       30 |   while (n)
          |          ^
          |          |
          |          (1) ⚠️  infinite loop here
          |          (2) when ‘n’ is non-NULL: always following ‘true’ branch... ─>─┐
          |                                                                         │
          |                                                                         │
          |┌────────────────────────────────────────────────────────────────────────┘
       31 |│    {
       32 |│      sum += n->val;
          |│             ~~~~~~
          |│              |
          |└─────────────>(3) ...to here
      ‘while_loop_missing_next’: event 4
       32 |       sum += n->val;
          |       ~~~~^~~~~~~~~
          |           |
          |           (4) looping back... ─>─┐
          |                                  │
      ‘while_loop_missing_next’: event 5
          |                                  │
          |┌─────────────────────────────────┘
       30 |│  while (n)
          |│         ^
          |│         |
          |└────────>(5) ...to here
    	

    I've added a warning emoji (⚠️) to the event in the path where the problem occurs (event 1 in the above), and I've added "ASCII art" to show control flow, such as the lines connecting events 2 and 3, and those connecting events 4 and 5 (compare with the GCC 14 output seen here).

    Another example of an execution path can be seen in this new -fanalyzer warning -Wanalyzer-undefined-behavior-ptrdiff, which warns about pointer subtractions involving different chunks of memory:

    demo.c: In function ‘test_invalid_calc_of_array_size’:
    demo.c:9:20: warning: undefined behavior when subtracting pointers [CWE-469] [-Wanalyzer-undefined-behavior-ptrdiff]
        9 |   return &sentinel - arr;
          |                    ^
      events 1-2
        │
        │    3 | int arr[42];
        │      |     ~~~
        │      |     |
        │      |     (2) underlying object for right-hand side of subtraction created here
        │    4 | int sentinel;
        │      |     ^~~~~~~~
        │      |     |
        │      |     (1) underlying object for left-hand side of subtraction created here
        │
        └──> ‘test_invalid_calc_of_array_size’: event 3
               │
               │    9 |   return &sentinel - arr;
               │      |                    ^
               │      |                    |
               │      |                    (3) ⚠️  subtraction of pointers has undefined behavior if they do not point into the same array object
               │
        

    There's a line on the left-hand side that visualizes the stack depth to highlight calls and returns.  As of GCC 15 this now uses unicode box-drawing characters (where the locale supports this), and for purely intraprocedual cases like the  -Wanalyzer-infinite-loop example above, we now omit it altogether, which saves some visual "noise."

    2. A new look for C++ template errors

    Compiler errors involving C++ templates are notoriously difficult to read.

    Consider this invalid C++ code:

    struct widget {};
    void draw (widget &);
    
    struct diagram {};
    void draw (diagram &);
    
    template <class W>
    concept drawable = requires(W w) { w.draw (); };
    
    template <drawable T>
    void draw(T);
    
    int main ()
    {
      draw (widget ());
    }

    Attempting to compile it with GCC 14 with -fconcepts -fconcepts-diagnostics-depth=2 gives 34 lines of output, which is relatively simple as far as these go, and even this can be hard to decipher. I'll post it here for reference, but I confess that my eyes tend to glaze over when I try to read it:

    <source>: In function 'int main()':
    <source>:15:8: error: no matching function for call to 'draw(widget)'
       15 |   draw (widget ());
          |   ~~~~~^~~~~~~~~~~
    <source>:2:6: note: candidate: 'void draw(widget&)' (near match)
        2 | void draw (widget &);
          |      ^~~~
    <source>:2:6: note:   conversion of argument 1 would be ill-formed:
    <source>:15:9: error: cannot bind non-const lvalue reference of type 'widget&' to an rvalue of type 'widget'
       15 |   draw (widget ());
          |         ^~~~~~~~~
    <source>:5:6: note: candidate: 'void draw(diagram&)'
        5 | void draw (diagram &);
          |      ^~~~
    <source>:5:12: note:   no known conversion for argument 1 from 'widget' to 'diagram&'
        5 | void draw (diagram &);
          |            ^~~~~~~~~
    <source>:11:6: note: candidate: 'template<class T>  requires  drawable<T> void draw(T)'
       11 | void draw(T);
          |      ^~~~
    <source>:11:6: note:   template argument deduction/substitution failed:
    <source>:11:6: note: constraints not satisfied
    <source>: In substitution of 'template<class T>  requires  drawable<T> void draw(T) [with T = widget]':
    <source>:15:8:   required from here
       15 |   draw (widget ());
          |   ~~~~~^~~~~~~~~~~
    <source>:8:9:   required for the satisfaction of 'drawable<T>' [with T = widget]
    <source>:8:20:   in requirements with 'W w' [with W = widget]
    <source>:8:43: note: the required expression 'w.draw()' is invalid, because
        8 | concept drawable = requires(W w) { w.draw (); };
          |                                    ~~~~~~~^~
    <source>:8:38: error: 'struct widget' has no member named 'draw'
        8 | concept drawable = requires(W w) { w.draw (); };
          |                                    ~~^~~~

    One of the issues is that there is a hierarchical structure to these messages, but we're printing them as a "flat" list, which obscures the meaning.

    I've been experimenting with a new way of presenting this information, taking inspiration from Sy Brand's excellent "Concepts Error Messages for Humans" paper. It's not ready to turn on by default in GCC for all C++ users, but it's available in GCC 15 through a command-line option for people who want to try it out: -fdiagnostics-set-output=text:experimental-nesting=yes

    Here's the example we just saw, adding the -fdiagnostics-set-output=text:experimental-nesting=yes "cheat code":

    demo.cc: In function ‘int main()’:
    demo.cc:19:8: error: no matching function for call to ‘draw(widget)’
       19 |   draw (widget ());
          |   ~~~~~^~~~~~~~~~~
      • there are 3 candidates
        • candidate 1: ‘void draw(widget&)’ (near match)
          demo.cc:6:6:
              6 | void draw (widget &);
                |      ^~~~
          • conversion of argument 1 would be ill-formed:
          • error: cannot bind non-const lvalue reference of type ‘widget&’ to an rvalue of type ‘widget’
            demo.cc:19:9:
               19 |   draw (widget ());
                  |         ^~~~~~~~~
        • candidate 2: ‘void draw(diagram&)’
          demo.cc:9:6:
              9 | void draw (diagram &);
                |      ^~~~
          • no known conversion for argument 1 from ‘widget’ to ‘diagram&’
            demo.cc:9:12:
                9 | void draw (diagram &);
                  |            ^~~~~~~~~
        • candidate 3: ‘template<class T>  requires  drawable<T> void draw(T)’
          demo.cc:15:6:
             15 | void draw(T);
                |      ^~~~
          • template argument deduction/substitution failed:
            • constraints not satisfied
              • demo.cc: In substitution of ‘template<class T>  requires  drawable<T> void draw(T) [with T = widget]’:
              • required from here
                demo.cc:19:8:   
                   19 |   draw (widget ());
                      |   ~~~~~^~~~~~~~~~~
              • required for the satisfaction of ‘drawable<T>’ [with T = widget]
                demo.cc:12:9:   
                   12 | concept drawable = requires(W w) { w.draw (); };
                      |         ^~~~~~~~
              • in requirements with ‘W w’ [with W = widget]
                demo.cc:12:20:   
                   12 | concept drawable = requires(W w) { w.draw (); };
                      |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
              • the required expression ‘w.draw()’ is invalid, because
                demo.cc:12:43:
                   12 | concept drawable = requires(W w) { w.draw (); };
                      |                                    ~~~~~~~^~
                • error: ‘struct widget’ has no member named ‘draw’
                  demo.cc:12:38:
                     12 | concept drawable = requires(W w) { w.draw (); };
                        |                                    ~~^~~~
    

    This presentation of the errors uses indentation and nested bullet points to show the logical structure of what the compiler is doing, eliminates redundant "visual noise" where it can, and clarifies the wording to state clearly that the compiler tried 3 different candidates for the function call, and spells out why each candidate was unsuitable. 

    I've tried turning this on for my day-to-day C++ work and it feels like a huge improvement. I hope we'll be able to turn it on by default in GCC 16; you can try it yourself here.

    3. Machine-readable diagnostics

    SARIF is a file format intended for storing the results of static analysis tools in a machine-readable, interchangeable format; as such, it's a great fit for compiler diagnostics. I added support in GCC 13 for writing out GCC's diagnostics in SARIF form, but it was an all-or-nothing deal: you could choose either GCC's classic text output on stderr, or SARIF, but not both. 

    For GCC 15, I've reworked the insides of how we handle diagnostics so that there can be multiple "output sinks," and added a new command-line option -fdiagnostics-add-output=ARGS for adding new sinks. For example, using -fdiagnostics-add-output=sarif will get you diagnostics emitted both as text on stderr and in SARIF form to a file. 

    Various sub-options are available; for example, -fdiagnostics-add-output=sarif:version=2.2-prerelease will select SARIF 2.2 output for that sink (though given that we're still working on the SARIF 2.2 specification, it uses an unofficial draft of the specification, and is subject to change).

    I've also improved the SARIF that GCC emits. The output now captures all locations and labeled source ranges associated with a diagnostic. For example, for:

    PATH/missing-semicolon.c: In function 'missing_semicolon':
    PATH/missing-semicolon.c:9:12: error: expected ';' before '}' token
        9 |   return 42
          |            ^
          |            ;
       10 | }
          | ~
    

    the GCC SARIF output now captures the secondary location (that of the trailing close brace), as well as that of the missing semicolon. Similarly, for:

    bad-binary-ops.c: In function ‘bad_plus’:
    bad-binary-ops.c:64:23: error: invalid operands to binary + (have ‘S’ {aka ‘struct s’} and ‘T’ {aka ‘struct t’})
      64 |   return callee_4a () + callee_4b ();
         |          ~~~~~~~~~~~~ ^ ~~~~~~~~~~~~
         |          |              |
         |          |              T {aka struct t}
         |          S {aka struct s}
    

    the SARIF output captures those underlined ranges and their labels. 

    GCC's SARIF output now captures the command-line arguments (§3.20.2), timestamps for the start and end of compilation (§§3.20.7-8), and the working directory (§3.20.19). It also now sets the roles property for SARIF artifact objects (§3.24.6), captures any embedded URLs in the text of messages (§3.11.6). For diagnostics relating to header files, the SARIF output now captures the chain of #include directives that led to the diagnostic's location (using SARIF locationRelationship objects, §3.34). 

    As well as improving the SARIF that GCC produces, I've added a tool to GCC 15 for consuming SARIF: sarif-replay. This is a simple command-line tool for viewing .sarif files, showing ("replaying") any diagnostics found in the .sarif files in text form as if they were GCC diagnostics, with support for details such as quoting source code, underlined ranges, fix-it hints, and diagnostic paths. 

    For example, here's a replay of a .sarif file emitted by GCC's -fanalyzer static analysis option:

    $ sarif-replay signal-warning.sarif
    In function 'custom_logger':
    signal.c:13:3: warning: call to ‘fprintf’ from within signal handler [-Wanalyzer-unsafe-call-within-signal-handler]
       13 |   fprintf(stderr, "LOG: %s", msg);
          |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      'main': events 1-2
        │
        │   21 | int main(int argc, const char *argv)
        │      |     ^~~~
        │      |     |
        │      |     (1) entry to ‘main’
        │......
        │   25 |   signal(SIGINT, handler);
        │      |   ~~~~~~~~~~~~~~~~~~~~~~~
        │      |   |
        │      |   (2) registering ‘handler’ as signal handler
        │
      event 3
        │
        │GNU C17:
        │ (3): later on, when the signal is delivered to the process
        │
        └──> 'handler': events 4-5
               │
               │   16 | static void handler(int signum)
               │      |             ^~~~~~~
               │      |             |
               │      |             (4) entry to ‘handler’
               │   17 | {
               │   18 |   custom_logger("got signal");
               │      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
               │      |   |
               │      |   (5) calling ‘custom_logger’ from ‘handler’
               │
               └──> 'custom_logger': events 6-7
                      │
                      │   11 | void custom_logger(const char *msg)
                      │      |      ^~~~~~~~~~~~~
                      │      |      |
                      │      |      (6) entry to ‘custom_logger’
                      │   12 | {
                      │   13 |   fprintf(stderr, "LOG: %s", msg);
                      │      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      │      |   |
                      │      |   (7) call to ‘fprintf’ from within signal handler
                      │

    4. An easier transition to C23

    When compiling C code, GCC 14 and earlier defaulted to -std=gnu17 (i.e., the "C17" version of the C standard, plus extensions). GCC 15 now defaults to -std=gnu23 (based on C23), so if your build system isn't specifying which C version to use, you might run into C17 versus C23 incompatibilities.

    I attempted to rebuild a large subset of Fedora with GCC 15 and thus defaulting to C23 to try to shake out problems that would arise, and in doing so found various diagnostics that needed improving. For example, bool, true, and false are keywords in C23, so I've tweaked the error message that occurs on old code such as:

    typedef int bool;

    so that you immediately know it's a C23 compatibility problem:

    <source>:1:13: error: 'bool' cannot be defined via 'typedef'
        1 | typedef int bool;
          |             ^~~~
    <source>:1:13: note: 'bool' is a keyword with '-std=c23' onwards

    Similarly, C17 and C23 treat function declarations without parameters such as int foo(); differently. In C23, it's equivalent to int foo(void); whereas, in earlier versions of C, such a declaration plays fast and loose with the type system—essentially meaning, "we don't know how many parameters this function takes or their types; let's hope your code is correct!". In my tests, this led to lots of errors on old code, such as in this example:

    #include <signal.h>
    
    void test()
    {
      void (*handler)();
      handler = signal(SIGQUIT, SIG_IGN);
    }

    So I've clarified these error messages so that they tell you the types of the functions (or function pointers) and show you where the pertinent typedef is:

    <source>: In function 'test':
    <source>:6:11: error: assignment to 'void (*)(void)' from incompatible pointer type '__sighandler_t' {aka 'void (*)(int)'} [-Wincompatible-pointer-types]
        6 |   handler = signal(SIGQUIT, SIG_IGN);
          |           ^
    In file included from <source>:1:
    /usr/include/signal.h:72:16: note: '__sighandler_t' declared here
       72 | typedef void (*__sighandler_t) (int);
          |                ^~~~~~~~~~~~~~
    

    Similarly, I've clarified the C front end's error messages for bad call sites:

    struct p { int (*bar)(); };
        
    void baz() {
        struct p q;
        q.bar(1);
    }
    t.c: In function 'baz':
    t.c:7:5: error: too many arguments to function 'q.bar'; expected 0, have 1
        7 |     q.bar(1);
          |     ^     ~
    t.c:2:15: note: declared here
        2 |         int (*bar)();
          |               ^~~
       

    showing the expected parameter count versus the actual argument count, underlining the first extraneous argument at the call site, and showing the pertinent field declaration of the callback.

    5. A revamped color scheme

    GCC will use color when emitting its text messages on stderr at a suitably modern terminal, using a few colors that seem to work well in a number of different terminal themes—but the exact rules for choosing which color to use for each aspect of the output have been rather arbitrary.

    For GCC 15, I've gone through C and C++'s errors, looking for places where two different things in the source are being contrasted, such as type mismatches. These diagnostics now use color to visually highlight and distinguish the differences. 

    For example, this error (Figure 1) shows a bogus attempt to use a binary + operator due to the two operands being structs (via typedefs S and T), rather than numeric types.

    screenshot of a C type error from GCC 15 showing color usage
    Figure 1: A new color scheme for errors in GCC 15.

    The two significant things here are the types, so GCC 15 uses two colors to consistently highlight the different types: in the message itself, in the quoted source, and the labels. Here, the left-hand type (typedef struct s S;) is shown throughout in green and the right-hand type (typedef struct t T;) in dark blue. I hope this approach better ties together the message's text with the source code and makes such errors a little easier to figure out.

    6. libgdiagnostics

    Figure 1 above shows off some of the features that GCC's diagnostics subsystem has: code for colorization, quoting source code, labelling ranges of source, fix-it hints, execution paths, SARIF output, and so on. Previously this code was hidden inside GCC and only usable by GCC itself. 

    For GCC 15, I've made this functionality available as a shared library for other projects to use: libgdiagnostics. There is a C API, along with C++ and Python bindings. For example, I was able to use the Python bindings to write a "linting" script for our testsuite, and "for free" got source quoting, colorization, and fix-it hints. Adding the ability to this script to output as SARIF would be a one-liner, rather than having to write lots of JSON-handling code.

    Try GCC 15

    We're still fixing bugs, but we hope that GCC 15 will be ready to officially release (as 15.1) sometime later this month. With my "downstream" hat on, we're already using the prerelease (GCC 15.0) within Fedora 42 Beta.

    Finally, you can use the excellent Compiler Explorer site to play with the new compiler. Have fun!

    脸上痣多是什么原因 伤口发痒是什么原因 涤纶是什么材料 腺是什么意思 含是什么意思
    南辕北辙是什么意思 什么精什么神 Rm是什么 运动后想吐是什么原因 吃什么容易发胖
    什么地方能做亲子鉴定 雨霖铃是什么意思 甲状腺低是什么意思 安踏高端品牌叫什么 列席是什么意思
    属羊的本命佛是什么佛 肿瘤是什么样子的 人类免疫缺陷病毒是什么 附件炎有什么症状 海棠果什么时候成熟
    蓝精灵是什么药clwhiglsz.com 心肌炎有什么症状和表现adwl56.com 经常吃维生素c有什么好处和坏处cj623037.com 1.16是什么星座hcv8jop5ns0r.cn 恏是什么意思gysmod.com
    什么的蜻蜓hcv7jop5ns2r.cn 胆红素高吃什么药hcv8jop1ns3r.cn 莳字五行属什么hcv8jop0ns3r.cn 糖类抗原是检查什么的hcv8jop8ns1r.cn 血压高吃什么药hcv9jop7ns3r.cn
    白色念珠菌是什么意思hcv9jop5ns6r.cn 专科和本科有什么区别hcv9jop6ns8r.cn 胃癌早期有什么症状yanzhenzixun.com 不假思索的假是什么意思yanzhenzixun.com 好男儿志在四方是什么生肖hcv9jop0ns0r.cn
    天珺手表什么档次hcv8jop7ns7r.cn 女人吃什么水果最好hcv9jop7ns3r.cn 肠道ct能检查什么bjcbxg.com 什么是理疗kuyehao.com 高回声是什么意思hebeidezhi.com

    Related Posts

    • New C++ features in GCC 15

    • How to implement C23 #embed in GCC 15

    • Improvements to static analysis in the GCC 14 compiler

    • The GDB developer's GNU Debugger tutorial, Part 1: Getting started with the debugger

    • Use compiler flags for stack protection in GCC and Clang

    • Install GCC and build a Hello World application on RHEL 9

    Recent Posts

    • Simplify access management for Red Hat Insights for Red Hat Enterprise Linux with new system roles

    • Intro to Redis and PostgreSQL in Red Hat SAP environments

    • Getting started with managed clusters migration

    • Retrieval-augmented generation with Llama Stack and Python

    • Introducing incident detection in Red Hat Advanced Cluster Management for Kubernetes 2.14

    What’s up next?

    Download the Advanced Linux Commands cheat sheet. You'll learn to manage applications and executables in a Linux operating system, define search criteria and query audit logs, set and monitor network access, and more.

    Get the cheat sheet
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    ? 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue

    百度