Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

C23:稍微好一点的C

Posted on 2024-01-22

肖像2018facebook.jpg

C 编程语言是最成熟且最流行的编程语言之一。它比较容易学习,而且实用性很强。

也许令人惊讶的是,C 编程语言一直在缓慢而谨慎地发展。如果您有 GCC 23 或 LLVM (Clang) 16,那么您已经拥有一个具有最新标准 (C23) 的一些功能的编译器。

 // 仅包含 stdio.h(如果存在)   # if __has_include ( < stdio.h > ) _ _   #包含< stdio.h >   #万一      #包含< stdlib.h >      [ [已弃用] ]   无效f ( ) { }      [ [不丢弃] ]   int g ( int x ) {   返回x + 1 ;   }      int main() {     F ( ) ; // 编译时警告:'f' 已弃用     克( 1 ) ; // 编译时警告     自动 x = 0 b 1111 ;     类型( x ) y = 1 '000' 000 ; // y 的类型与 x 相同     printf ( "%d \n " , x ) ; // 打印 15     printf ( "%d \n " , y ) ; // 打印 1000000     constexpr int N = 10 ;   // 使用 static_assert 进行编译时断言     static_assert ( N == 10 , "N 必须是 10 " ) ;     布尔a [ N ] ; // N 个布尔值的数组   for ( int i = 0 ; i < N ; + + i ) {       a [ i ] = true ;   }     printf ( "%d \n " , a [ 0 ] ) ; // 打印 1   }      
  1. 代码的第一部分包含一些预处理器指令,这些指令是编译器在编译源代码之前对其进行处理的指令。 #if指令在编译时检查条件,并且仅当条件为真时才包含以下代码。 __has_include宏是 C23 采用的 C++17 的一项功能,用于检查头文件是否存在并可以包含。在这种情况下,它没有用,因为我们知道stdio.h存在,但在其他情况下,这对于确定可用的标头很有用。
  2. 代码的下一部分定义了两个带有属性的函数,这些属性是注释,为编译器提供有关函数、变量、类型等的行为或用法的附加信息。
    • [[deprecated]] 属性是 C23 采用的 C++14 的一项功能,它将函数标记为已过时并阻止其使用。如果调用或引用该函数,编译器将发出警告。
    • [[nodiscard]] 属性是 C23 采用的 C++17 的一项功能,表示函数的返回值不应被忽略或丢弃。如果从废弃值表达式调用该函数,编译器将发出警告。

    在这种情况下,函数 f 已被弃用并且不执行任何操作,而函数 g 返回输入值加一,不应被忽略。主函数的前两行调用函数 f 和 g 并触发警告。

  3. main 函数的第三行使用 auto 关键字声明变量 x,这是 C++11 的一项功能,可让编译器从变量的初始值设定项推断变量的类型。在这种情况下,初始值设定项是二进制文字,这是 C++14 的一项功能,并被 C23 采用,允许使用前缀 0b 以二进制表示法写入整数常量。 x的值为0b1111,相当于十进制的15。
  4. 第四行使用 typeof 运算符声明另一个变量 y,该运算符返回表达式的类型。在本例中,表达式为 x,因此 y 的类型与 x 的类型相同。 y 的初始值设定项是数字分隔符,这是 C23 采用的 C++14 的一项功能,允许在数字文字中的数字之间插入单引号以提高可读性。 y 的值为 1’000’000,相当于十进制的 1000000。
  5. 第七行用constexpr关键字声明了一个常量变量N,这是C23采用的C++11的一个特性,表明可以在编译时计算该变量的值。 N 的值为10。以前,人们经常使用宏来定义编译时常量(例如#define N 10 )。
  6. 第八行使用 static_assert 关键字,这是 C23 采用的 C++11 的一个功能,用于执行编译时断言检查。该关键字采用布尔表达式和可选字符串消息作为参数。如果表达式为 false,编译器将发出错误并停止编译,并显示消息。如果表达式为真,编译器将不执行任何操作。在本例中,表达式为 N == 10,为真,因此编译继续。
  7. 第九行声明了一个名为 a 的 N 个布尔值数组。数组是存储在连续内存位置的相同类型元素的集合。数组的大小必须是常量表达式,这就是为什么 N 用 constexpr 声明。我们还使用关键字 true 和 false,它们成为 C23 中的标准。

C23 中还有更多功能,但编译器和系统库需要一些时间才能跟上。

到目前为止我的想法:

  • 在 C 中引入 consexpr 可能有助于减少对宏的依赖,这通常是一个好主意。宏在 C 中运行良好,但是当引入错误时,可能很难获得有意义的错误消息。这种情况不会经常发生,但在大型代码库中,这可能会成为一个问题。
  • 我个人很少在其他语言中使用 auto 和 typeof,因此我不希望在 C 中使用它们。但是,在某些特定情况下,它可以极大地简化代码。这可能有助于减少对宏的依赖。
  • static_assert 背后的想法很棒。您运行的检查不会影响软件的性能,甚至可能会有所帮助。它很便宜,而且可以捕捉讨厌的虫子。它对于 C 来说并不陌生,但采用 C++ 语法是一个好主意。
  • __has_include功能可以简化对不同编译器的支持。这是个好主意。

原文: https://lemire.me/blog/2024/01/21/c23-a-slightly-better-c/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme