C99标准的意义是什么?

14

C99为该语言添加了几个有用的功能,但我发现很难推荐依赖于C99的任何实践方法。这是因为很少(或者根本没有?)实际实现C99语言。当然,一些编译器有限的支持,但是没有人想花时间编写C代码,并使其不可移植。

鉴于标准已经编写和最终确定了超过10年了,这是令人沮丧的。此外,我时不时听到关于C1x的讨论,我想知道为什么有人会采取修订语言的步骤,而当前版本的语言尚未实现。

那么我的问题是:作为今天的普通C程序员,C99标准对我有哪些实用价值(如果有的话)?


1
就像旁路一样,我想你必须建立标准。但是gcc实际上试图更接近实现C99,而不像MSVC。 - Pascal Cuoq
1
@Pascal:我发现很难相信,考虑到GCC开发人员已经有十年时间了,仍然没有实现新标准的主要部分,因此支持C99在他们的优先事项清单中排名较高。 - Billy ONeal
2
@Billy 当前的C99修订版是2007年发布的。 - Šimon Tóth
1
@Billy 这取决于您认为什么是“基本部分”。此外,标准中的更改数量与所需的编译器代码更改没有任何关系。 - Šimon Tóth
3
除了MSVC以外,所有常用的C编译器都在某种程度上支持C99。 - JeremyP
显示剩余2条评论
6个回答

14

C99引入了一些功能,使得在C语言中编程更加容易且安全:

  • 指定初始化
  • 复合字面量
  • for-域变量
  • 固定宽度整型

C语言也更具表现力,包括:

  • 可变参数宏
  • inline函数

在我的Linux机器上,我有四个编译器支持C99,可以满足日常使用需求:gccclangopenccicc

前两个是开源编译器,其中clang试图与gcc兼容(即C99的支持程度大致相同)。

后两个来自两个主要CPU生产商,是商业软件,但对非商业用户有慷慨的许可政策。它们的C99支持有点差异,特别是对于inline的支持似乎不完全符合标准。


能否提供 opencc 的官方网站链接? - Matt Joiner
Windows 版本的 icc 是否支持 C99? - Billy ONeal
@Billy,我不使用Windows,所以我不确定。但是如果它不能支持至少语言本身,那将会令人惊讶。然而,C库的支持可能是另一个问题。 - Jens Gustedt
复合字面量自动存储期限的lvalue是否使语言更安全、更具表现力? 复合字面量rvalue是一个不错的补充,静态期限的常量复合字面量也很好,但是复合字面量lvalue无法控制的短暂生命周期使它们似乎比手动创建的变量更容易出错。 - supercat
@supercat,复合字面量至少具有在表达式之前声明的变量所具有的生命周期。这与C++的临时对象不同,后者绑定到表达式。它们与其他对象一样绑定到作用域。 - Jens Gustedt
@JensGustedt:如果在语句之前立即声明一个变量,然后需要将该语句移动到嵌套作用域中(例如通过“if”语句控制),则仍然可以将变量保留在该作用域之外。我不知道如何使用复合字面量来实现这一点,除非在新作用域之外创建一个适当类型的新变量并适当初始化它(这不需要复合字面量)。 - supercat

8

MSVC不支持C99,而且可能永远都不会支持。但是微软没有太多更新他们的C编译器的动力。他们不会因为这个失去太多业务。

但有很多编译器支持C99。

http://en.wikipedia.org/wiki/C99#Implementations

关于gcc:

http://gcc.gnu.org/c99status.html

你说得对,也许C99对于库代码并不实用(如果没有Microsoft的支持可能永远不会实用),但是如果你在做内部或个人项目时可以自己选择编译器和工具,那么可移植性就不是什么问题了。


2
请提供实际回答我的问题的答案,而不是与我争论。 - Billy ONeal
5
没人会质疑MSVC不支持C99这个事实。如果那是你想要听到的,你应该重新表达问题。 - Šimon Tóth
2
微软将在新的C++标准正式包含其中许多C99特性后支持它们。他们不关心C,但他们不想在C++世界中落后。 - R.. GitHub STOP HELPING ICE
2
@R,MSVC是否支持在编译C代码时混合声明和代码?上次我使用它时(已经有一段时间了),它并不支持,尽管这是C++中允许的。我的更大的问题是:微软是否实际声称他们将向C编译器添加重叠功能,还是只是假定? - Matthew
3
@Billy,如果你不受限于不支持C99的环境(尤其是嵌入式系统),那么就应该使用C99。如果你知道你的库将被使用MSVC的用户使用,那么在接口中不能使用C99特性,但在实现中使用C99是没有任何理由不这样做的(当然除了库特性依赖之外)。 - Šimon Tóth
显示剩余2条评论

7
关于C1x,我认为值得注意的是标准委员会很清楚C99并没有被广泛采用,并且不想重复同样的错误(或者让情况变得更糟)。从C1x宪章中可以看到:(链接):“与C9X不同的是,在伦敦会议上达成的共识是不应该进行任何发明,毫无例外。只有那些具有历史并由商业实现普遍使用的功能应该被考虑。此外,必须小心地将这些功能标准化,以使标准和商业实现兼容。”
还有:
“最初的标准在用户和供应商社区中都得到了非常积极的反响。然而,C99并没有被广泛接受。”

4
考虑采用那些无用的 MS 功能时,我发现很难认真对待这些陈述。这些功能是为了破坏 C 和可移植性而创建的,而且没有其他人想要支持这些功能。 - R.. GitHub STOP HELPING ICE
5
如果您在谈论各种“安全”字符串函数的话,我认为它们是一件好事情。(或者,它们也可以使用 strlcpystrlcat;我不在意。)根据定义,任何扩展都“破坏了可移植性”,但将其纳入标准的目的是为了解决这个问题。此外,如果这意味着微软可能真的想要与 C1x 同步,那将是很棒的。 - jamesdlin
在我看来,与其说“没有发明”,不如指定可以通过宏在现有编译器上模拟的功能,但是如果有新编译器的支持可能会更好(例如,“向右旋转”和“向左旋转”的标准定义宏,可以通过调用(希望)内联函数来模拟,但也可以扩展到编译器内部函数)。如果xy是“简单变量”,(x>>y) | (x >> (31-y) >> 1)可能会转换为一系列糟糕的指令,而__rotright(x,y)更可能产生单个指令。 - supercat

4
当你没有被限制在不支持C99的环境中时(尤其是嵌入式系统),你应该使用C99。
如果你知道你的库将被使用MSVC的人使用,那么你不能在接口中使用C99特性,但在实现中使用C99没有理由不这样做(当然,除了库功能依赖关系)。
原始答案:“啥?有哪些编译器不支持C99?另外,当你从编译器转向工具时,C99实际上比C89更常见。”

4
我不知道有哪些编译器支持C99。无论是GCC还是MSVC都不支持,这些是我经常使用的唯一编译器。 - Billy ONeal
2
@Billy 嗯,如果你认为这个状态是不支持的 http://gcc.gnu.org/c99status.html 那我猜你真的不能用任何编程语言写代码了 :-) 一旦一个标准被"支持",它就已经过时了。MSVC实际上正式支持C吗? - Šimon Tóth
1
根据该页面,wctype.hstdint.h中大部分有用的内容都缺失了。我对其他缺失的内容不是110%熟悉,但这些是重要的功能块,现在却不在那里。 - Billy ONeal
2
我认为你需要支持你的说法:“C99实际上比C89更常见。” - jamesdlin
1
@Billy ONeal:我认为wctype.h所“缺失”的只是宽字符格式字符串检查,而这在C99中并没有规定——这只是一个“好用的”功能。stdint.h仅在“某些平台”上缺失。 - caf
显示剩余5条评论

2

如果您关心性能,那么离不开使用restrict


1

FreeBSD现在使用Clang进行内核编译,而且它几乎支持C99。


2
实际上,Clang 只支持 C99 :-) - Šimon Tóth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接