-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
By writing separate construction and assignment, plus the new feature of suppressing assignment to a member by writing `member = _ ;` (now allowed only in assignment operators). I do realize that's an "opt-out" which I normally prefer to avoid, but: - I considered and decided against (for now) the alternative of not having assignment be memberwise by default. I want to keep the (new to Cpp2) default of memberwise semantics for assignment as with construction. I think that's a useful feature, and normally if you do assign to a member it doesn't arise, and so I think it makes sense to explicitly call out when we're choosing not to do any assignment at all to a member before doing other assignment processing. We'll get experience with how it goes. - `_` is arguably natural here, since it's pronounced "don't care." There too, we'll see if that is natural generalized, or feels strained. For now it feels natural to me.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
"8A21:1546" | ||
"8A27:1514" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4812,7 +4812,32 @@ class cppfront | |
|| found_default_init | ||
); | ||
|
||
// Emit the initializer... | ||
// Emit the initializer if it it isn't '_' (don't care) and ... | ||
if (initializer == "_") { | ||
// I'll walk the walk: I've said publicly that _structured_ goto is perfectly | ||
// kosher -- it's only _unstructured_ goto that's harmful (and Dijkstra knew it), | ||
// which means: | ||
// - jumping into a block or statement (I'm looking at you, Duff's Device) | ||
// - jumping backwards (that's an unstructured loop == spaghetti control flow) | ||
// - jumping across a variable declaration (C++ already bans this) | ||
// | ||
// But jumping forward-and-outward, skipping no declarations, is righteous. | ||
// | ||
// Here, using goto is the right tool for the job, and is better code because: | ||
// - it avoids a gratuitous extra level of nesting inside an | ||
// 'if (initializer != "_")' block of the next 100 lines (and please don't | ||
// start the other diatribe about that the next 100 lines should be a | ||
// separate named function - no it shouldn't) | ||
// - which extra indent of identical code would make GitHub's diff for this | ||
// commit super hard to read (diff does not deal well with blocks of code | ||
// that simply change indentation level - in fact seeing that diff without | ||
// the goto was the tipping point to just switch to goto here) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
JohelEGP
Contributor
|
||
// ... but sadly I feel the need to defend it. | ||
// | ||
// As Scott would say (and has said), "so sue me" | ||
// | ||
goto skip_initializer; | ||
} | ||
|
||
if (initializer.empty()) { | ||
initializer = "{}"; | ||
|
@@ -4909,6 +4934,8 @@ class cppfront | |
separator = ", "; | ||
} | ||
|
||
skip_initializer: ; | ||
|
||
// And on to the next data member... | ||
++object; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1190,22 +1190,30 @@ union: (inout t : meta::type_declaration) | |
} | ||
|
||
// Add the destructor | ||
t.add_member( " operator=: (move this) = { _destroy(); } " ); | ||
t.add_member( " operator=: (move this) = { _destroy(); }" ); | ||
|
||
// Add default constructor | ||
t.add_member( " operator=: (out this) = { _discriminator = -1; } " ); | ||
t.add_member( " operator=: (out this) = { }" ); | ||
|
||
// Add value-set | ||
(copy value_set: std::string = " operator=: (out this, that) = {\n") | ||
// Add copy/move construction and assignment | ||
(copy value_set: std::string = "") | ||
{ | ||
for alternatives | ||
do (a) { | ||
value_set += " if that.is_(a.name)$() { set_(a.name)$( that.(a.name)$() ); }\n"; | ||
} | ||
|
||
value_set += " _discriminator = that._discriminator;\n"; | ||
value_set += " }\n"; | ||
t.add_member( value_set ); | ||
|
||
t.add_member( std::string(" operator=: (out this, that) = {\n") | ||
+ " _storage = ();\n" | ||
+ " _discriminator = -1;\n" | ||
+ value_set | ||
); | ||
t.add_member( std::string(" operator=: (inout this, that) = {\n") | ||
+ " _storage = _;\n" | ||
+ " _discriminator = _;\n" | ||
This comment has been minimized.
Sorry, something went wrong.
gregmarr
Contributor
|
||
+ value_set | ||
); | ||
} | ||
} | ||
|
||
|
Oh, the "hide whitespace only changes" feature is only implemented in pull requests?