问题描述
在回答中
结果表明,程序可能具有未定义的行为依赖"(des Pudels Kern 在这个问题中)一个实现如何使用标准给出的实现余地.例如,[expr.prim.lambda.closure]/2:
it was shown that a program could have undefined behavior "depending on" (des Pudels Kern in this question) how an implementation used implementation leeway given by the standard. As an example, [expr.prim.lambda.closure]/2:
闭包类型声明在最小的块作用域,类作用域,或包含相应 lambda 表达式的命名空间范围.[...]闭包类型不是聚合类型.安实现可能定义的闭包类型不同于下面描述,前提是这不会改变可观察到的行为除了更改以外的程序:
- (2.1) 尺寸和/或闭包类型的对齐,
- (2.2) 闭包类型是否可简单复制 ([class.prop]),或
- (2.3) 闭包类型是否为标准布局类([class.prop]).[...]
- (2.1) the size and/or alignment of the closure type,
- (2.2) whether the closure type is trivially copyable ([class.prop]), or
- (2.3) whether the closure type is a standard-layout class ([class.prop]). [...]
在对答案的评论中指出这种情况不是实现定义的行为
It was pointed out in a comment to the answer that this scenario is not implementation-defined behavior
实现定义"具有非常具体的含义([intro.abstract]/2);事实并非如此.
在这种实现余地上具有未定义行为 (UB) 的程序是否会具有无条件的 UB,可能按照 [intro.abstract]/5?或者如何用标准术语描述这样的程序?
Would a program which had undefined behavior (UB) conditionally on such implementation leeway, have unconditional UB, possibly as per [intro.abstract]/5? Or how would such a program be described, in standardese terms?
推荐答案
假设我正确理解了问题,这里是一个更简单的例子:
Assuming I understand the question correctly, here is a simpler example:
void* storage = ::operator new(100);
new (storage) std::string;
在某些语言实现中,字符串适合内存,此示例程序的行为将被定义.但该标准不提供任何语言实现满足该假设的保证,并且在该假设不成立的语言实现中,行为是未定义的.
In some language implementation, where the string fits in the memory, the behaviour of this example program would be defined. But the standard does not provide a guarantee that any language implementation satisfies that assumption and in language implementation where the assumption doesn't hold, the behaviour is undefined.
有条件地未定义行为,具体取决于语言实现.同样适用于问题中描述的更微妙的例子.
The behaviour is undefined conditionally, depending on the language implementation. Same applies to the more subtle example described in the question.
它不是实现定义";行为,因为标准没有说它是实现定义的";使用那些引用的话.如果标准确实这么说,那就意味着语言实现必须记录这种行为.实际上,没有要求记录闭包类型是否可以简单地复制.
It's not "implementation defined" behaviour because the standard doesn't say that it's "implementation defined" using those quoted words. If standard did say that, it would imply that language implementation must document that behaviour. As it is, there is no requirement to document whether closure type is trivially copyable.
为了避免使用具有特殊含义的短语,我们可以使用替代词,例如implementationdependent";或未指定"改为描述情况.
To avoid this phrase with special meaning, we can use alternatives such as "implementation dependent" or "unspecified" to describe the situation instead.
如果您希望编写可移植到当前标准的任何语言实现的程序,包括将来存在的那些您目前无法知道其实现的程序,您不应无条件地依赖此类实现细节.
If you wish to write programs that are portable to any language implementation of the current standard, including one's that exist in the future whose implementation you cannot know at the moment, you should not unconditionally rely on such implementation details.
您可以使用类型特征来观察闭包是否可以简单地复制,并且只有在格式良好且定义良好时才有条件地使用 std::bit_cast
- 如果您有充分的理由这样做所以.
You could use a type trait to observe whether the closure is trivially copyable, and conditionally use std::bit_cast
only when it is well formed and well defined - if you have a good reason to do so.
这篇关于未定义行为 (UB) 以实现余地为条件的程序是具有无条件 UB 的程序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!