c++之是否可以根据 C++20 中稍后的运行时决定存在不同的隐式对象

lautakyan007 阅读:14 2024-11-24 20:56:43 评论:0

这个问题是指添加P0593latest C++20 draft .

这是我的例子:

#include <cstdlib> 
#include <cstdio> 
 
void foo(void *p) 
{ 
    if ( std::getchar() == 'i' ) 
    { 
        *(int *)p = 2; 
        std::printf("%d\n", *(int *)p); 
    } 
    else 
    { 
        *(float *)p = 2; 
        std::printf("%f\n", *(float *)p); 
    } 
} 
 
int main() 
{ 
    void *a = std::malloc( sizeof(int) + sizeof(float) ); 
    if ( !a ) return EXIT_FAILURE; 
 
    foo(a); 
    // foo(a);    [2] 
} 

此代码是否针对最新草案下的所有输入进行了明确定义?

P0593 中表达的基本原理相当清楚地表明取消注释 [2]如果两个用户输入项不同,则会由于严格的别名违规而导致未定义的行为。隐式对象创建应该只发生一次,在 malloc 处。 ;它不是由 foo 中的赋值语句触发的.

对于程序的任何实际运行,都存在一个未指定的隐式对象集的成员,可以使程序定义良好。但是我不清楚 [intro.object]/10 中提到的隐式对象创建的选择是否必须在 malloc 时进行。发生;或者决定是否可以“时间旅行”。

对于将二进制 blob 读入缓冲区然后做出如何访问它的运行时决定(例如反序列化;并且 header 告诉我们是浮点数还是整数即将出现)的程序,可能会出现同样的问题。

请您参考如下方法:

The implicit object creation is supposed to happen just once, at the point of malloc; it isn't triggered by the assignment statement in foo.



那不相关。重要的是创建了哪个对象。该标准说,被创建的对象是一个将本来应该是 UB 的东西变成定义良好的代码的对象:

that operation implicitly creates and starts the lifetime of zero or more objects of implicit-lifetime types ([basic.types]) in its specified region of storage if doing so would result in the program having defined behavior.



行为最终基于运行时执行,而不是静态分析。因此,您只需要跟踪程序的执行,直到遇到未定义行为的情况,但如果在相关操作时在该存储中创建了某种类型的对象,则会定义行为。

因此,创建的位置始终是“操作”,但确定创建的内容是基于运行时如何使用内存(即:行为)。


标签:C++
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号