Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"as if" in language standards

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?

like image 752
R Samuel Klatchko Avatar asked Feb 21 '10 16:02

R Samuel Klatchko


People also ask

What is a standard language?

from English Grammar Today A standard language is a variety of language that is used by governments, in the media, in schools and for international communication. There are different standard varieties of English in the world, such as North American English, Australian English and Indian English.

Should learners of English use standard forms of the language?

All users of English make choices all the time about what is most acceptable or appropriate in different contexts. Learners of English should use standard forms of the language in most situations. 08 Either … or…

What is the as-if rule in programming?

This rule is commonly referred to as the as-if rule . The rule has three main exceptions. The first is that programs exhibiting undefined behavior are exempt; since the observable behavior is not well-defined anyway, any transformation is valid.

What is a non-standard form of a language?

In contrast, there are non-standard forms of a language that are used, for example, in different regional dialects and these non-standard varieties are different from each other. This book is a grammar of standard written and spoken British English.


2 Answers

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.

like image 100
Michael Burr Avatar answered Oct 13 '22 01:10

Michael Burr


If the change in allocator in operator new makes an observable difference in the behaviour of a compliant C++ program then yes, it might require a change in the implementation of the no-throw version. Specifically if operator delete expects only blocks allocated by the new allocator then the no-throw new must change.

My reading is that the use of as if allows an implementation such as yours when the user hasn't overriden the standard operator new. As soon as he has, the implementation must not use a malloc based no-throw operator new and must either call the user declared version explicitly or at least re-use enough of the user declared version that a conforming program cannot tell that this isn't how the no-throw version has been implemented.

like image 29
CB Bailey Avatar answered Oct 13 '22 03:10

CB Bailey