为什么一致性实现的行为不同。有内部链接的不完全数组类型?的后续问题。
上下文:默认情况下,在gcc和clang (一致性实现)中,需求C11、6.9.2p3.1被取消,该请求被定位为扩展。
问题:扩展可以在保持实现一致性的同时取消现有的标准要求吗?
1 C11,6.9.2外部对象定义,3:
如果对象的标识符声明为暂定定义并具有内部链接,则声明的类型不应是不完整类型。
UPD。是。换句话说:标准说:“我们不支持这一点,诊断是必需的”。扩展说:“我们确实支持这一点(因此,标准所需的诊断是不相关的)”。
发布于 2021-08-06 17:30:52
与其说实现用扩展“取消”了需求,不如说是扩展添加了标准不支持的特性。主要的要求是扩展不会改变任何严格一致的程序。
一致性实现的定义来自于C11标准的第4p6节
这两种形式的一致性实现是托管和独立的。合格的托管实现应接受任何严格符合的程序。符合规范的独立实现应接受任何严格符合的程序,其中库子句(第7条)中指定的特性的使用仅限于标准标头的内容.为了简洁而省略..。符合的实现可能有扩展(包括附加的库函数),只要它们不改变任何严格符合的程序的行为
在第4p5节中定义了严格符合的程序:
严格符合标准的程序只应使用本国际标准中规定的语言和库的特性。它不应产生依赖于任何未指定的、未定义的或实现定义的行为的输出,并且不应超过任何最低实现限制。
在第4p7节中定义了一致性程序:
一个符合的程序是一个符合的实现是可以接受的。
因此,考虑到你之前的问题中的程序:
static int arr[ ];
int main( void )
{
return arr[ 0 ];
}
static int arr[ ] = { 0 };这不是一个严格一致的程序,因为它违反了6.9.2p3。然而,gcc等一些实现允许将此作为扩展。支持这样的特性并不会阻止类似的严格一致的程序,如
static int arr[1];
int main( void )
{
return arr[ 0 ];
}
static int arr[ ] = { 0 };不会有任何不同的行为。因此,支持此特性的实现仍然可以被视为符合规范的实现。这也意味着第一个程序,而不是一个严格的符合程序,是一个符合的程序,因为它将在符合的实现上以一种定义良好的方式运行。
发布于 2021-08-06 17:07:07
标准要求,如果程序违反约束节中的约束,则实现必须至少发出一次诊断。没有关于文档是否有意义或与违反约束有任何关系的要求。一个无条件输出“警告:此实现不试图强制执行其作者认为愚蠢的约束”的实现就足够了。类似地,包含命令行选项的实现输出这样的消息和文档,除非指定了该选项,否则它可能不符合。
请注意,即使是这种要求也有漏洞:如果程序超过了实现的转换限制,则实现可以以任何方式运行,不受任何限制,不需要发出任何类型的诊断。尽管“标准”要求每个实现至少有一个源程序至少在名义上行使“标准”中给出的翻译限制而不会导致实现故障,但实现可以对翻译限制的交互方式施加任意限制,例如允许程序包含最多63个字符的一个标识符,或者数量更多的不超过三个字符的标识符。很少有情况下,不符合规范的实现可能会对特定的源文本进行任何操作,从而使其不符合。
https://stackoverflow.com/questions/68683211
复制相似问题