我常常看到人们争论代码不是标准的。他们真正的意思是什么?
例如,如果我愿意:
itoa()将整数转换为字符,他们会通过暗示“代码是非标准的!”来忽略它。
答案 0 :(得分:10)
C ++标准的某些实现允许某些不应被允许的事物。
如果您使用这些功能,可能会说您的代码不符合标准。
以下是一个例子:
int x = 5;
char arr[x];
上述代码在C ++ 03标准中是不允许的,但在C99中是允许的。有人说声称实现C ++ 03的一些编译器允许你在C ++程序中使用该代码。
答案 1 :(得分:6)
标准代码表示根据相关语言的标准具有明确定义的行为的代码。大多数编译器根据其用户群实现许多扩展。依赖于这些扩展的代码是非标准的。简单的例子是枚举范围或MSVC中的__uuidof(T)。我对其他编译器的评论并不十分熟悉,但我知道他们有自己的扩展。
答案 2 :(得分:3)
也许他们的意思是“不符合ANSI C / C ++标准。”但是从你的问题的措辞和你没有发布的代码中无法分辨出来。
答案 3 :(得分:2)
有不同程度的'非标准'。
代码在特定编译器上定义良好,但不是标准代码,因为它使用扩展。这样做的问题在于它使代码的可移植性降低(这取决于问题可能是你必须要忍受的)。这是itoa()
的问题之一 - 它不是标准的,因此它可能是您正在使用的系统之外的系统上的问题。
通常,许多程序员认为,如果您可以选择以便携/标准方式执行某些操作,则应选择相应的非标准方法。特别是在像Stackoverflow这样的地方发帖时,在各种各样的平台上工作的人都可以查看答案,符合标准的答案可能拥有最广泛的受众。对于itoa)
的情况,snprintf()
函数是使用标准函数获得与itoa()
类似的结果的一种方法。
在处理未定义的行为时,有时会在答案中提出标准合规性,其中事情似乎在特定测试中起作用,但根据标准,对构造的行为方式没有承诺。这不仅仅是可移植性的问题;看似有效的未定义行为非常危险,因为“工作”行为可能会变为崩溃或导致细微错误发生的事情。这种变化可以出于任何原因发生。
对于未指定的行为(编译器可以选择程序应该如何工作的几个选项之一)或者实现定义的行为(编译器可以选择多个选项之一),但是具有类似但不那么激烈的情况记录它的作用。在这些情况下,即使程序可能符合标准,可移植性仍然是一个问题。
答案 4 :(得分:1)
人们对“标准”C ++的另一个意思不仅仅是使用作为标准一部分的编译器的功能,而且只使用标准库。因此,如果你去comp.lang.c ++,那么主题上唯一的问题就是“标准C ++”。这意味着没有UI等。
坦率地说,纯粹的标准C ++几乎完全没用。除了最小的实用程序和学术练习之外,如果你要做任何事情,你必须使用一些提供非标准功能的库。你应该尽可能地坚持标准,否则当你尝试跨越实现时,你将有更多的工作要做,包括简单的升级。
答案 5 :(得分:1)
有标准文档可以控制C和C ++程序的结构和行为。每个版本都有在线版本,虽然这些是技术上的工作文件,而不是“官方”标准文件(官方文件不能免费下载);但是,它们对于大多数用途来说已经足够好了:
两种标准都定义了语言的语法,语义和核心库。诸如gcc或MSVC之类的单独实现可以自由地将它们自己的扩展添加到语言语法和库中; itoa
就是这样一个库扩展。
问题是,如果编写代码以使用这些扩展,则不会在不同的编译器下编译。如果您只打算在Windows或Linux上运行代码,这不一定是个问题,但如果您希望它在上运行,则必须限制自己使用语言标准定义的内容(或者在模块中隔离特定于平台的扩展,这些扩展可以轻松地换出。
答案 6 :(得分:1)
C和C ++语言被定义为ISO标准。这些标准文档描述了如何执行C和C ++代码,什么是有效的,什么不是,以及该语言的其他所有内容。
只要您的代码仅依赖于这些标准所保证的内容,那么您可以假设您的代码可以在任何平台上与任何编译器一起使用。
但是,大多数编译器还支持一些“额外”,以标准中未提及的函数形式(例如itoa
),或者可能是特殊语法,或某些结构略有不同的含义。 (例如,如果您使用Microsoft的C ++编译器,那么volatile
除标准中描述的内容之外还有一些其他影响)
当您依赖此类扩展时,您的代码将不再可移植。你不能在另一个编译器上编译它,并期望它只是工作。以您提到的itoa
函数为例,该函数可能不存在,具体取决于我选择的编译器,因此如果我尝试在那里编译它,我的代码就会中断。
因此,通常最好坚持使用语言标准所保证的内容。如果标准不能保证函数存在,那么如果您希望代码可移植,则不应该假设它存在。
答案 7 :(得分:0)
嗯,对于itoa(),这是Posix(unix)名称而不是'标准化'ISO名称_itoa(),正如jalf所说,这必须具有可移植性。
答案 8 :(得分:-1)
我在UBuntu
附带的编译器上看到的一个最奇怪的功能是你可以取消引用一个未初始化的指针。这恰好在我的程序空间中使用了内存。
我不知道哪个版本的UBuntu,但我和我的教授非常困惑地看到这一点。我记得在这种情况下结果是1。