“如同”在语言标准 [英] "as if" in language standards

查看:147
本文介绍了“如同”在语言标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标准中的as if这个短语的确切含义是什么,以及当用户可以修改行为的各个部分时,它的工作原理。



问题是关于C ++标准时谈到nothrow版本 operator new 。 18.4.1.1/7 read(我的强调):


这个nothrow版本的operator new返回 strong>从普通版本中获取。


我的理解是,as不需要特定的实现,是适当的。所以如果 operator new 是这样实现的(我知道这不是一个合规的实现,因为没有循环或使用new_handler;但我缩短,我的问题):

  //注意 - 不完全符合 - 仅供参考。 
void * operator new(std :: size_t s)
{
void * p = malloc(s);
if(p == 0)
throw std :: bad_alloc();
return p;
}

然后,这样写nothrow版本是合法的:

  //注意 - 不完全符合 - 仅供参考。 
void * operator new(std :: size_t s,const std :: nothrow_t& nt)
{
return malloc(s)但是让我们假设一个程序替换 operator new

使用一些其他分配器。 as if是指编译器必须自动更改nothrow版本的行为才能使用其他分配器?

解决方案

从1.9开始程序执行:


符合实现需要模拟抽象机器的可观察行为


和信息脚注:


此规定有时称为as-if规则,自由地忽略本国际标准的任何要求,只要结果好像已经遵守了要求,只要可以从程序的可观察的行为确定即可。例如,实际实现不需要评估表达式的一部分如果它可以推断出其值未被使用,并且没有产生影响程序的可观察行为的副作用。


特别注意,as-if要求是在 operator new()的nothrow版本的替换版本上绑定。但是,正如我读的,这个要求将落在程序员重写 operator new()而不是编译器。这个责任的另一面是,我认为标准几乎需要的默认实现nothrow 运算符new()由库提供必须做一些事情沿着调用在try / catch中抛出 new ,如果捕获 std :: bad_alloc ,则返回0。



如果编译器/链接器/任何聪明到足以弄清楚当默认抛出 new(如果规则) )被使用,默认非抛出 new()可以采取快捷方式,但如果默认抛出 new()被覆盖,默认的非抛出 new()必须有不同的行为。我相信这在技术上是可能的一个实现(即使你可能无法表示它在标准C ++)。我会惊讶,如果有一个实现这样做。



我可能读得太多的要求,但我认为这是可以推断。 / p>

What is the exact meaning of the phrase "as if" in the standard and how does it work when a user can modify individual parts of the behavior.

The question is in regards to the C++ standard when talking about the nothrow version of operator new. 18.4.1.1/7 reads (my emphasis):

This nothrow version of operator new returns a pointer obtained as if acquired from the ordinary version.

My understanding is that "as if" does not require a specific implementation as long as the behavior is appropriate. So if operator new was implemented like this (I know this is not a compliant implementation as there is no loop or use of the new_handler; but I'm shortening that to focus on my issue):

// NOTE - not fully compliant - for illustration purposes only.
void *operator new(std::size_t s)
{
    void *p = malloc(s);
    if (p == 0)
        throw std::bad_alloc();
    return p;
}

Then it would be legal to write the nothrow version like this:

// NOTE - not fully compliant - for illustration purposes only.
void *operator new(std::size_t s, const std::nothrow_t &nt)
{
    return malloc(s);
}

But let's say a program replaces operator new to use some other allocator. Does "as if" mean the compiler has to automatically change the behavior of the nothrow version to use this other allocator? Is the developer required to replace both the plain and nothrow versions?

解决方案

From 1.9 "Program execution:

conforming implementations are required to emulate (only) the observable behavior of the abstract machine

and in an informational footnote:

This provision is sometimes called the "as-if" rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.

The standard does specifically note that the "as-if" requirement is binding on a replacement version of the nothrow version of operator new(). However, as I read it, that requirement would fall to the programmer overriding operator new() not the compiler. The flip side of this responsibility is that I think the standard pretty much requires the default implementation of the nothrow operator new() provided by the library must do something along the lines of calling the throwing new in a try/catch and return 0 if std::bad_alloc is caught.

Where the "as if rule" could come in to play here is if the compiler/linker/whatever were smart enough to figure out that when the default throwing new() was in being used, the default non-throwing new() could take the shortcut, but if the default throwing new() was overridden, the default non-throwing new() would have to act differently. I'm sure this is technically possible for an implementation (even if you probably can't express it in standard C++). I'd be surprised if there was ever an implementation that did this.

I might be reading too much into the requirement, but I think that's what can be inferred.

这篇关于“如同”在语言标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆