language-lawyer

Why are async state machines classes (and not structs) in Roslyn?

天大地大妈咪最大 提交于 2019-12-29 11:43:53
问题 Let’s consider this very simple async method: static async Task myMethodAsync() { await Task.Delay(500); } When I compile this with VS2013 (pre Roslyn compiler) the generated state-machine is a struct. private struct <myMethodAsync>d__0 : IAsyncStateMachine { ... void IAsyncStateMachine.MoveNext() { ... } } When I compile it with VS2015 (Roslyn) the generated code is this: private sealed class <myMethodAsync>d__1 : IAsyncStateMachine { ... void IAsyncStateMachine.MoveNext() { ... } } As you

Why are async state machines classes (and not structs) in Roslyn?

為{幸葍}努か 提交于 2019-12-29 11:42:21
问题 Let’s consider this very simple async method: static async Task myMethodAsync() { await Task.Delay(500); } When I compile this with VS2013 (pre Roslyn compiler) the generated state-machine is a struct. private struct <myMethodAsync>d__0 : IAsyncStateMachine { ... void IAsyncStateMachine.MoveNext() { ... } } When I compile it with VS2015 (Roslyn) the generated code is this: private sealed class <myMethodAsync>d__1 : IAsyncStateMachine { ... void IAsyncStateMachine.MoveNext() { ... } } As you

Why is {}+[] different from ({}+[])? [duplicate]

别说谁变了你拦得住时间么 提交于 2019-12-29 08:13:44
问题 This question already has answers here : What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012? (5 answers) Closed 3 years ago . I was recently alarmed to discover the following: > {}+[] 0 > ({}+[]) "[object Object]" > {}+[]+1 1 > ({}+[])+1 '[object Object]1' > {}+[] == ({}+[]) false Why does wrapping something in parenthesis change its type? 回答1: {} + [] is an empty block followed by a an array with a unary + operator, which is

Implementing a std::vector like container without undefined behavior

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-29 08:07:55
问题 It may surprise some coders and, as surprising as it can be, it is not possible to implement std::vector without non-standard support of the compilers. The problem essentially resides on the ability to perform pointer arithmetic on a raw storage region. The paper, p0593: Implicit creation of objects for low-level object manipulation, that appears in @ShafikYaghmour answer, exposes clearly the problematic and proposes modification of the standard in order to make implementation of vector like

Strict aliasing and overlay inheritance

試著忘記壹切 提交于 2019-12-29 06:52:09
问题 Consider this code example: #include <stdio.h> typedef struct A A; struct A { int x; int y; }; typedef struct B B; struct B { int x; int y; int z; }; int main() { B b = {1,2,3}; A *ap = (A*)&b; *ap = (A){100,200}; //a clear http://port70.net/~nsz/c/c11/n1570.html#6.5p7 violation ap->x = 10; ap->y = 20; //lvalues of types int and int at the right addrresses, ergo correct ? printf("%d %d %d\n", b.x, b.y, b.z); } I used to think that something like casting B* to A* and using A* to manipulate the

Is there a simple, portable way to determine the ordering of two characters in C?

两盒软妹~` 提交于 2019-12-29 06:01:28
问题 According to the standard: The values of the members of the execution character set are implementation-defined. (ISO/IEC 9899:1999 5.2.1/1) Further in the standard: ...the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. (ISO/IEC 9899:1999 5.2.1/3) It appears that the standard requires that the execution character set includes the 26 uppercase and 26 lowercase letters of the Latin alphabet, but I see no requirement that

Is there a simple, portable way to determine the ordering of two characters in C?

人走茶凉 提交于 2019-12-29 06:00:08
问题 According to the standard: The values of the members of the execution character set are implementation-defined. (ISO/IEC 9899:1999 5.2.1/1) Further in the standard: ...the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. (ISO/IEC 9899:1999 5.2.1/3) It appears that the standard requires that the execution character set includes the 26 uppercase and 26 lowercase letters of the Latin alphabet, but I see no requirement that

Why are arbitrary target expressions allowed in for-loops?

我的梦境 提交于 2019-12-29 02:47:10
问题 I accidentally wrote some code like this: foo = [42] k = {'c': 'd'} for k['z'] in foo: # Huh?? print k But to my surprise, this was not a syntax error. Instead, it prints {'c': 'd', 'z': 42} . My guess is that the code is translated literally to something like: i = iter(foo) while True: try: k['z'] = i.next() # literally translated to assignment; modifies k! print k except StopIteration: break But... why is this allowed by the language? I would expect only single identifiers and tuples of

Is it allowed to write an instance of Derived over an instance of Base?

时光总嘲笑我的痴心妄想 提交于 2019-12-29 01:44:06
问题 Say, the code class Derived: public Base {....} Base* b_ptr = new( malloc(sizeof(Derived)) ) Base(1); b_ptr->f(2); Derived* d_ptr = new(b_ptr) Derived(3); b_ptr->g(4); d_ptr->f(5); seems to be reasonable and LSP is satisfied. I suspect that this code is standard-allowed when Base and Derived are POD, and disallowed otherwise (because vtbl ptr is overwritten). The first part of my question is: please point out precise precondition of such an overwrite. There may exist other standard-allowed

Why is calling non virtual member function on deleted pointer an undefined behavior?

那年仲夏 提交于 2019-12-29 01:43:25
问题 As, the title says: Why is calling non virtual member function on deleted pointer an undefined behavior? Note the Question does not ask if it is an Undefined Behavior, it asks Why it is undefined behavior. Consider the following program : #include<iostream> class Myclass { //int i public: void doSomething() { std::cout<<"Inside doSomething"; //i = 10; } }; int main() { Myclass *ptr = new Myclass; delete ptr; ptr->doSomething(); return 0; } In the above code, the compiler does not actually