19

It has been established (see below) placement new is required to create objects

int* p = (int*)malloc(sizeof(int));
*p = 42;  // illegal, there isn't an int

Yet that is a pretty standard way of creating objects in C.

The question is, does the int exist if it is created in C, and returned to C++?

In other words, is the following guaranteed to be legal? Assume int is the same for C and C++.

foo.h

#ifdef __cplusplus
extern "C" {
#endif

int* foo(void);

#ifdef __cplusplus
}
#endif

foo.c

#include "foo.h"
#include <stdlib.h>

int* foo(void) {
    return malloc(sizeof(int));
}

main.cpp

#include "foo.h"
#include<cstdlib>

int main() {
    int* p = foo();
    *p = 42;
    std::free(p);
}

Links to discussions on mandatory nature of placement new:

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Passer By
  • 19,325
  • 6
  • 49
  • 96
  • For `int` yes, for arbitrary types it depends. – user0042 Oct 24 '17 at 11:17
  • No do you don't need placement new to create objects. Plain `new`, `new[]`, or as shown `malloc` can be used as well (with the caveat that `malloc` doesn't call the constructor, only allocates memory). – Some programmer dude Oct 24 '17 at 11:17
  • @Someprogrammerdude I thought the three links specifically said `malloc` is insufficient – Passer By Oct 24 '17 at 11:18
  • 2
    For one or more values of a primitive type (like `int`) you can use `malloc` just fine. Or `new`. Or `new[]`. That `malloc` call you show is exactly equal to `new int`. I.e. `int* p = (int*) malloc(sizeof(int));` and `int* p = new int;` are the same, both allocate memory enough to store one `int` value. – Some programmer dude Oct 24 '17 at 11:20
  • There is however another possible problem with your `foo` function: What if the C and C++ compiler have different sizes for `int`? Probably very unlikely, but it's still something you have to consider. – Some programmer dude Oct 24 '17 at 11:25
  • 1
    @Someprogrammerdude Let us exclude that just for now. That is of course an issue – Passer By Oct 24 '17 at 11:27
  • another quasi-dupe: [clarification of specifics of P0137](https://stackoverflow.com/questions/40930475/clarification-of-specifics-of-p0137), particularly this quote: `Drafting note: this maintains the status quo that malloc alone is not sufficient to create an object` – underscore_d Oct 24 '17 at 11:33
  • @underscore_d It used to be that "The lifetime of an object is a runtime property of the object. The lifetime of an object of type T begins when: — storage with the proper alignment and size for type T is obtained," (end of story for POD types) was taken seriously. – curiousguy Oct 26 '17 at 07:49
  • C++ is autistic. It doesn't even recognize the existence of anything that is not C++; so there is no std answer! – curiousguy Oct 26 '17 at 08:07
  • "_Drafting note: this maintains the status quo that malloc alone is not sufficient to create an object_" If you take that seriously, than you also need to accept that any use of a union in C++ was undefined, until the std C++ finally choose to define what can change the active member!!! (which is beyond preposterous) – curiousguy Nov 09 '17 at 06:33
  • 5
    You can call malloc directly from a C++ program, no need to go through a custom C function. Anyone who maintains that malloc *should not* be enough to create an int needs to be taken out and shot. If there is language in the standard that makes malloc not enough to create an int, it's a defect that needs to be fixed. End of story. – n. m. could be an AI Nov 09 '17 at 07:02
  • 2
    I'd second @n.m.: Looking at a language as a language-laywer takes you only so far. In the end, you must implement the thing on a real machine, and that's where you must leave the comfy realm of standard-defined C and enter the realm of implementation-defined C and, gasp, assembler. You see, it's simply not possible to implement either `malloc()` or `::operator new()` with 100% standard conforming C/C++. That fails both when you need to back your allocation with memory requested from the kernel, and when you reuse a free'd object for something else (strict aliasing violation!). – cmaster - reinstate monica Nov 09 '17 at 11:51

7 Answers7

5

Yes! But only because int is a fundamental type. Its initialization is vacuous operation:

[dcl.init]/7:

To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type, constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution. The constructor thus selected is called, with an empty argument list, to initialize the object.

  • If T is an array type, each element is default-initialized.

  • Otherwise, no initialization is performed.

Emphasis mine. Since "not initializing" an int is akin to default initialing it, it's lifetime begins once storage is allocated:

[basic.life]/1:

The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and
  • if the object has non-vacuous initialization, its initialization is complete,

Allocation of storage can be done in any way acceptable by the C++ standard. Yes, even just calling malloc. Compiling C code with a C++ compiler would be a very bad idea otherwise. And yet, the C++ FAQ has been suggesting it for years.


In addition, since the C++ standard defers to the C standard where malloc is concerned. I think that wording should be brought forth as well. And here it is:

7.22.3.4 The malloc function - Paragraph 2:

The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.

The "value is indeterminate" part kinda indicates there's an object there. Otherwise, how could it have any value, let alone an indeterminate one?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/158608/discussion-on-answer-by-storyteller-existence-of-objects-created-in-c-functions). – Andy Nov 09 '17 at 13:42
  • Per [\[intro.object\]/1](https://timsong-cpp.github.io/cppwp/intro.object#1.sentence-2) you don't actually have an object. Would you agree that means that `[basic.life]/1` does not apply and the code is not legal? – NathanOliver Sep 26 '19 at 18:46
  • @Nathan - I consider the wording that doesn't allow an object to be a defect, myself. So far all hope is for http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0593r4.html to fix it. – StoryTeller - Unslander Monica Sep 26 '19 at 18:58
  • Thanks for the paper, it was a good read. I guess we can call it sane undefined behavior ;) – NathanOliver Sep 26 '19 at 19:40
4

I think the question is badly posed. In C++ we only have the concepts of translation units and linkage, the latter simply meaning under which circumstances names declared in different TUs refer to the same entity or not.

Nothing is virtually said about the linking process as such, the correctness of which must be guaranteed by the compiler/linker anyway; even if the code snippets above were purely C++ sources (with malloc replaced with a nice new int) the result would be still implementation defined ( eg. consider object files compiled with incompatible compiler options/ABIs/runtimes ).

So, either we talk in full generality and conclude that any program made of more than one TU is potentially wrong or we must take for granted that the linking process is 'valid' ( only the implementation knows ) and hence take for granted that if a function from some source language ( in this case C ) primises to return a 'pointer to an existing int' then the the same function in the destination language (C++) must still be a 'pointer to an existing int' (otherwise, following [dcl.link], we could't say that the linkage has been 'achieved', returning to the no man's land).

So, in my opinion, the real problem is assessing what an 'existing' int is in C and C++, comparatively. As I read the correponding standards, in both languages an int lifetime basically begins when its storage is reserved for it: in the OP case of an allocated(in C)/dynamic(in c++) storage duration object, this occurs (on C side) when the effective type of the lvalue *pointer_to_int becomes int (eg. when it's assigned a value; until then, the not-yet-an-int may trap(*)).

This does not happen in the OP case, the malloc result has no effective type yet. So, that int does not exist neither in C nor in C++, it's just a reinterpreted pointer.

That said, the c++ part of the OP code assigns just after returning from foo(); if this was intended, then we could say that given that malloc() in C++ is required having C semantics, a placement new on the c++ side would suffice to make it valid (as the provided links show).

So, summarizing, either the C code should be fixed to return a pointer to an existing int (by assigning to it) or the c++ code should be fixed by adding placement new. (sorry for the lengthy arguing ... :))


(*) here I'm not claiming that the only issue is the existence of trap representation; if it were, one could argue that the result of foo() is an indeterminate value on C++ side, hence something that you can safely assign to. Clearly this is not the case because there are also aliasing rules to take into account ...
Massimiliano Janes
  • 5,524
  • 1
  • 10
  • 22
  • "_Nothing is virtually said about the linking process as such_" do you mean linking between languages? – curiousguy Nov 05 '17 at 23:42
  • 1
    @curiousguy, no in that passage I meant the linking process in general; the std says that you can combine TU's to form an executable binary image according to linkage rules, but says nothing how this concretely happens; in fact, it's easy to compile two TU's with different compiler switches, link them successfully, yet invoking UB at runtime. – Massimiliano Janes Nov 06 '17 at 07:53
  • @curiousguy, of course the std does impose limits on entities defined in different TU's ( in this sense, that statement feels a bit exaggerated ), but here we're talking about the physical process forming the final binary and how that reflects the orginal code semantics... – Massimiliano Janes Nov 06 '17 at 08:34
  • "_it's easy to compile two TU's with different compiler switches, link them successfully, yet invoking UB at runtime_" ...and it's easy to compile two TU's with different **compilers**, link them successfully, yet invoking UB at runtime – curiousguy Nov 06 '17 at 13:22
  • "_the std says that you can combine TU's to form an executable binary image according to linkage rules_" The std does not even mention compiling then linking as distinct phases. There is only the well formed program comprised of TU. **It may not even possible to separately compile anything!** – curiousguy Nov 06 '17 at 13:28
  • @curiousguy and I agree with you ( see the first paragraph ); do you believe this contrasts with what it's written in the answer ? if yes, how ? – Massimiliano Janes Nov 06 '17 at 13:40
  • As my previous comment said "C++ is autistic. It doesn't even recognize the existence of anything that is not C++" – curiousguy Nov 06 '17 at 20:30
  • @curiousguy and I agree with you again, the question cannot be answered standard-wise; but, the point of my answer is that once the compiler/linker are thrown into the mix ( and these do tell us what a *successful/correct* link is ) the question *can* be answered in quite general terms. – Massimiliano Janes Nov 07 '17 at 08:03
  • Yes, the practical answer is that separate compilation stops all information flow and the question is void. – curiousguy Nov 07 '17 at 14:40
  • All talk and no references. Where does any of this come from? – n. m. could be an AI Nov 09 '17 at 07:40
  • @n.m. What comes from where? – curiousguy Nov 09 '17 at 08:05
  • Any of the assertions made in the answer. They should be derived from somewhere. – n. m. could be an AI Nov 09 '17 at 08:17
  • @n.m. heck your're right, but the answer would explode in length and verbosity then. Note that the point of the answer is mainly to show that the question is illl-posed unless something more is assumed about the linkage process. For any other concrete issue you can find plenty of answers here on SO. Anyway, I'll add some more references when I have time ... – Massimiliano Janes Nov 09 '17 at 08:54
  • @n.m. in fact, consider the currently top-voted answer: albeit being rich of references and quotes, it does not answer the question at all; it evades the real issue, that is what makes a function call semantically correct when passing language boundaries... – Massimiliano Janes Nov 09 '17 at 09:07
4

I can identify two parts of this question that should be addressed separately.


Object lifetime

It has been established (see below) placement new is required to create objects

I posit that this area of the standard contains ambiguity, omission, contradiction, and/or gratuitous incompatibility with existing practice, and should therefore be considered broken.

The only people who should be interested in what a broken part of the standard actually says are the people responsible for fixing the breakage. Other people (language users and language implementors alike) should defer to existing practice and common sense. Both of which say that one does not need new to create an int, malloc is enough.

This document identifies the problem and proposes a fix (thanks @T.C. for the link)


C compatibility

Assume int is the same for C and C++

It is not enough to assume that.

One also needs to assume that int* is the same, that the same memory is accessible by C and C++ functions linked together in a program, and that the C++ implementation does not define the semantics of calls to functions written in the C programming language to be wiping your hard drive and stealing your girlfriend. In other words, that C and C++ implementations are compatible enough.

None of this is stipulated by the standard or should be assumed. Indeed, there are C implementations that are incompatible with each other, so they cannot be both compatible with the same C++ implementation.

The only thing the standard says is "Every implementation shall provide for linkage to functions written in the C programming language" (dcl.link) What is the semantics of such linkage is left undefined.

Here, as before, the best course of action is to defer to existing practice and common sense. Both of which say that a C++ implementation usually comes bundled with a compatible enough C implementation, with the linkage working as one would expect.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
2

The question is meaningless. Sorry. This is the only "lawyer" answer possible.

It is meaningless because the C++ and the C language ignore each others, as they ignore anything else.

Nothing in either language is described in term of low level implementation (which is ridiculous for languages often described as "high level assembly"). Both C and C++ are specified (if you can call that a specification) at a very abstract level, and the high and low levels are never reconnected. This generates endless debates about what undefined behaviors means in practice, how unions work, etc.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
  • 2
    *"the C++ and the C language ignore each others"* - That's false. The C++ standard considers the C standard a normative reference. It defers to it at times. – StoryTeller - Unslander Monica Nov 09 '17 at 07:54
  • The C++ in no way accept that there is a C language that can be used to write code that might work together with C++ code in any well defined way. **Please prove me wrong, as this is a sorry state of affairs, I hope I am wrong.** "_The C++ standard considers the C standard a normative reference. It defers to it at times_" as a paper saving measure only. That does not mean anything. It just means other ISO books exist in the library. – curiousguy Nov 09 '17 at 08:14
  • As a "paper saving" measure only? Doesn't mean anything? Do you understand what a **normative reference** is? [If you don't believe me, read the standard own take on it](https://timsong-cpp.github.io/cppwp/n4659/intro.refs#1). – StoryTeller - Unslander Monica Nov 09 '17 at 08:16
  • I contributed to the C++ std. Did you? What do you not understand in the proposition P = "there is a C language that can be used to write code that might work together with C++ code in any well defined way"? Can you prove P? – curiousguy Nov 09 '17 at 08:20
  • Oh, I'd love to see the contribution. I really would. – StoryTeller - Unslander Monica Nov 09 '17 at 08:22
  • Which definition of a C++ concept refers to a C definition? – curiousguy Nov 09 '17 at 08:29
  • There's [this one](https://timsong-cpp.github.io/cppwp/n4659/memory#c.malloc-2), as an example. And since you brought it up, I have no intention to let you off the hook. What contribution did you make that supposedly gives you some authority? – StoryTeller - Unslander Monica Nov 09 '17 at 08:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/158586/discussion-between-curiousguy-and-storyteller). – curiousguy Nov 09 '17 at 08:33
  • @curiousguy "I contributed to the C++ std" So can we hold you responsible for all the errors, omissions, contradictions and overall poor language language in the standard? Great. – n. m. could be an AI Nov 09 '17 at 08:38
  • @n.m. My conclusion is that C and C++ are both too awful to be fixed, at many levels. There is a mismatch between high level and low level. Overall, it is a failure and my recommandation is to not use either where correctness is the goal. – curiousguy Nov 09 '17 at 08:44
  • 2
    I agree with curiousguy for once: the topic in the question is not covered by any of the C or C++ standards. There is no attempt in either standard to specify a cross-language memory model , and the C++ standard's model is incompatible with the C standard's . – M.M Nov 09 '17 at 09:11
  • @curiousguy You ask for proof for C++ considering C: C++ does have the `extern "C" {}` feature precisely for the reason of working together with libraries implemented in C. Without this feature, you would not be able to mix C and C++ code in the same process, as C++ name mangling would make it impossible to call a C function from C++, and vice versa. – cmaster - reinstate monica Nov 09 '17 at 11:42
  • @cmaster From a logical/mathematical POV, there is nothing that can be used for proof of C/C++ valid interaction. OTOH, intent seems clear. – curiousguy Nov 09 '17 at 11:45
  • This answer took quite a digging around in the comments to make sense. Some of what you said in chat should be structured and included as context, especially for the sentence _"the C++ and the C language ignore each other"_ – Passer By Nov 09 '17 at 15:58
1

Although neither the C Standard nor, so far as I know, the C++ Standard officially recognizes the concept, almost any platform which allows programs produce by different compilers to be linked together will support opaque functions.

When processing a call to an opaque function, a compiler will start by ensuring that the value of all objects that might legitimately be examined by outside code is written to the storage associated with those objects. Once that is done, it will place the function's arguments in places specified by the platform's documentation (the ABI, or Application Binary Interface) and perform the call.

Once the function returns, the compiler will assume that any objects which an outside function could have written, may have been written, and will thus reload any such values from the storage associated with those objects the next time they are used.

If the storage associated with an object holds a particular bit pattern when an opaque function returns, and if the object would hold that bit pattern when it has a defined value, then a compiler must behave as though the object has that defined value without regard for how it came to hold that bit pattern.

The concept of opaque functions is very useful, and I see no reason that the C and C++ Standards shouldn't recognize it, nor provide a standard "do nothing" opaque function. To be sure, needlessly calling opaque functions will greatly impede what might otherwise be useful optimizations, but being able to force a compiler to treat actions as opaque function calls when needed may make it possible to enable more optimizations elsewhere.

Unfortunately, things seem to be going in the opposite direction, with build systems increasingly trying to apply "whole program" optimization. WPO would be good if there were a way of distinguishing between function calls that were opaque because the full "optimization barrier" was needed, from those which had been treated as opaque simply because there was no way for optimizers to "see" across inter-module boundaries. Unless or until proper barriers are added, I don't know any way to ensure that optimizers won't get "clever" in ways that break code which would have had defined behavior with the barriers in place.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • GNU's `asm("");` isn't even well specified regarding what's reachable by the C/C++ -> ABI -> C/C++ transition. – curiousguy Jul 02 '18 at 23:50
1

I believe it is legal now, and retroactively since C++98!

Indeed the C++ specification wording till C++20 was defining an object as (e.g. C++17 wording, [intro.object]):

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is created by a definition (6.1), by a new-expression (8.5.2.4), when implicitly changing the active member of a union (12.3), or when a temporary object is created (7.4, 15.2).

The possibility of creating an object using malloc allocation was not mentioned. Making it a de-facto undefined behavior.

It was then viewed as a problem, and this issue was addressed later by https://wg21.link/P0593R6 and accepted as a DR against all C++ versions since C++98 inclusive, then added into the C++20 spec, with the new wording.

The wording of the standard are quite vague and may even seem to use tautology, defining a well defined implicitly-created objects (6.7.2.11 Object model [intro.object]) as:

implicitly-created objects whose address is the address of the start of the region of storage, and produce a pointer value that points to that object, if that value would result in the program having defined behavior [...]

The example given in C++20 spec is:

#include <cstdlib>
struct X { int a, b; };
X *make_x() {
   // The call to std​::​malloc implicitly creates an object of type X
   // and its subobjects a and b, and returns a pointer to that X object
   // (or an object that is pointer-interconvertible ([basic.compound]) with it), 
   // in order to give the subsequent class member access operations   
   // defined behavior. 
   X *p = (X*)std::malloc(sizeof(struct X));
   p->a = 1;   
   p->b = 2;
   return p;
}

It seems that the `object` created in a C-function as in the OP question, falls into this category and is a valid object. Which would be the case also for allocation of C-structs with malloc.

Amir Kirsh
  • 12,564
  • 41
  • 74
0

No, the int does not exist, as explained in the linked Q/As. An important standard quote reads like this in C++14:

1.8 The C ++ object model [intro.object]
[...] An object is created by a definition (3.1), by a new-expression (5.3.4) or by the implementation (12.2) when needed. [...]

(12.2 is a paragraph about temporary objects)

The C++ standard has no rules for interfacing C and C++ code. A C++ compiler can only analyze objects created by C++ code, but not some bits passed to it form an external source like a C program, or a network interface, etc.

Many rules are tailored to make optimizations possible. Some of them are only possible if the compiler does not have to assume uninitialized memory contains valid objects. For example, the rule that one may not read an uninitialized int would not make sense otherwise, because if ints may exist anywhere, why would it be illegal to read an indeterminate int value?

This would be a standard compliant way to write the program:

int main() {
    void* p = foo();
    int i = 42;
    memcpy(p, &i, sizeof(int));
    //std::free(p);   //this works only if C and C++ use the same heap.
}
alain
  • 11,939
  • 2
  • 31
  • 51
  • *"The C++ standard has no rules for interfacing C and C++ code"* - A bit harsh, wouldn't you say? There are *some* rules. – StoryTeller - Unslander Monica Oct 24 '17 at 13:10
  • 2
    I haven't found an explicit one, do you have an example? – alain Oct 24 '17 at 13:16
  • Are you seriously suggesting C++ doesn't interface with C at all? – StoryTeller - Unslander Monica Oct 24 '17 at 14:10
  • 2
    No, of course not, all I'm saying is the C++ standard does not talk about it. – alain Oct 24 '17 at 14:12
  • 1
    "_For example, the rule that one may not dereference a pointer that points past the end of an array would not make sense otherwise_" Nope. Irrelevant. – curiousguy Oct 26 '17 at 07:53
  • "_Remember, many rules are tailored to make optimizations possible_" Remember, the C++ cannot know how many placement new calls are in separately compiled C code (answer: as many as needed to start lifetime of objects according to whatever your reading of the C++ std will be assumed by the C++ compiler). – curiousguy Nov 06 '17 at 13:33
  • placement new does not exist in C @curiousguy. – alain Nov 06 '17 at 13:40
  • Are you implying that a call to C function cannot result in a constructor call? – curiousguy Nov 06 '17 at 20:31
  • Yes, sort of. There is no constructor for an `int` anyway, in this example. My main point is that you need to use some C++ way to tell the compiler that this `int` really exists, because else the compiler would have to assume valid `int`s anywhere. But apparently I'm quite alone with this view. Btw I have read some of your answers to similar questions, and I agree that these rules are really annoying for us programmers sometimes. But that's how they are, we can't change them. – alain Nov 06 '17 at 20:39
  • The cited passage directly contradicts \[basic.life] "The lifetime of an object of type T begins when: (1.1) — storage with the proper alignment and size for type T is obtained and ..." (next one is irrelevant for an `int`). Surely a lifetime cannot begin for an object that was not created. In any case there's a defect because the intent of the standard is not to invalidate a huge massive of existing code that uses `malloc` to create objects. – n. m. could be an AI Nov 09 '17 at 07:54
  • @alain "_placement new does not exist in C_" is not even false; it's meaningless, as C++ does not recognize that C exist as a programming language that can coexist with C++. **Since in the context of C++, placement new is defined in C++, it is not possible to determine that an analog exist or does not exist in C.** This is also true of `int`. – curiousguy Nov 09 '17 at 08:07
  • **C++ concepts only exist on the scope of the C++ std like local var exist in the scope of the function.** You cannot have C++ concepts that exist in C, at least from a lawyer POV, because there is nothing in C++ that defines the behavior of anything that is not C++. – curiousguy Nov 09 '17 at 08:09
  • @curiousguy "C++ does not recognize that C exist" wrong, the C++ standard incorporates the C standard by reference and defers to it explicitly many times. "Every implementation shall provide for linkage to functions written in the C programming language" (dcl.link) – n. m. could be an AI Nov 09 '17 at 08:31
  • @n.m. And "linkage to functions" is defined somewhere? Does it provide defined semantics for any program? I don't see how it could, given that the C++ (like the C) is defined in term of high level concepts which are only meaningful in C++. So is dcl.link/3 anything but a supplication? "**please, try to make that work, for some definition of 'work' which every programmer with the spirit and intuition of C and C++ will agree on**". Formally C and C++ have nothing in common. C++ is not C plus features. – curiousguy Nov 09 '17 at 08:50
  • @curiousguy The standard as a whole is a supplication. There is nothing in it that is a law of the land, or a mathematical theorem, or anything like that. You use it in conjunction with common sense and best practice of the industry. It has no meaning outside of these things. – n. m. could be an AI Nov 09 '17 at 08:55
  • Ppl here disagree on common sense re: lifetime of PODs, union, memcpy, what is a pointer value, and strict aliasing. Please see my questions about pointers! – curiousguy Nov 09 '17 at 08:59
  • @curiousguy no. People disagree on existing wording and rarely try to contemplate *needed* wording. The latter requires common sense, the former does not. – n. m. could be an AI Nov 09 '17 at 09:59
  • For me it's not a contradiction to try to understand the standard as un-biased as possible, and at the same time use common sense when writing programs. There is `-fno-strict-aliasing` for example, and even without this flag many things just work as expected. @n.m. I found the ['Schrödingers object' argument](https://stackoverflow.com/questions/40873520/reinterpret-cast-creating-a-trivially-default-constructible-object/40874245#40874245) quite convincing, for why allocating memory is probably not enough to create objects. – alain Nov 09 '17 at 11:23
  • What really puzzles me is why the standard committee does not clarify this one way or the other in an unambigous way. – alain Nov 09 '17 at 11:24
  • 1
    @alain The standard is not a gospel, it can be broken, and is at times. This is one of those times. – n. m. could be an AI Nov 09 '17 at 11:33