Friday, June 14, 2013

FeedaMail: Comments for Sutter’s Mill

feedamail.com Comments for Sutter's Mill

Comment on GotW #93: Auto Variables, Part 2 by Róbert Dávid

@Unsigned Int:

(How odd name you got :) )

Come on, it’s the textbook case of the new hammer. Not everything is a nail – you don’t have to use auto for everything. auto is for the case of storing the result of a function/expression, with the appropriate type – you don’t want to do that here, rather you want to define a cycle variable, of a given type (size_t), initialized to zero.

Auto is for when you want a variable of a ‘meh, idontcare’ type. If you want a given type, declare with the given type.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Yuri Khan

In Solution 1a, you suggest checking the iterator increment against distance(i, end) when writing strided loops. While this will work correctly (as opposed to just i += 2), it introduces a potential performance bug: It will compile even if the iterator does not provide random access. In this case, the loop becomes O(n^2).

I think the cleanest way to write a generic strided loop would be to write a helper template to use instead of the unchecked increment:

  template <typename Iter>  void advance_up_to(Iter& it, ptrdiff_t n, Iter&& end)  {      while (n --> 0 && it != end) ++it;  }  

(suitably specialized for various iterator categories to handle negative counts and take advantage of random access where available).

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by saul

3. My only concern on using auto is my IDE doesn’t autocomplete through such variables, making it annoying enough to not use half the time.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by John Smith

Doesn’t the indexed version for(auto i = 0; i < v.size(); i += 2) set i to be of type int? If v.size() is (say) 64 bits while int is 32 the loop will never end, will it not?

The C++11 version of as_(un)signed is using make_signed_t, which is really C++14. It should be using typename make_(un)signed::type instead.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Arne Mertz

In the last lines of 2(b) you write about vector sizes < 2^(sizeof(int)-1). It should be 2^(CHAR_BIT*sizeof(int)-1). I ran into that pitfall some time ago ;-)

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Anders Dalvander

You mention

for( auto i = 0; i < v.size(); i += 2 )

as a potential solution for 1 when you mention the silent narrowing conversion in 2b. Perhaps we should have a `std::vector::size_type std::vector::zero() const` member function?

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by rhalbersma

Last time I checked the Standard section 18.4.1, the fixed-size integer types from were optional. Are there any proposals that make it mandatory to provide intN_t and uintN_t for platforms that compile for N-bits architectures?

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Tom

How come we’re back to using c-style casts?
auto x = uint64_t(x + y);

Why not
auto x = static_cast(x + y);

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Petter

John and Anders: that was my thought as well.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Juraj Blaho

Does the cast in as_signed not exhibit signed overflow? I thought that code like the following exhibits signed overflow which would be UB:

  unsigned u = -1;// A large value not representable by signed int  auto i = int(u);// <-- UB?  

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by pip010 (@ppetrovdotnet)

one of the most annoying thin in c# is :
var variable = SomeFunctionCall();

now you have to go hunt in the declaration of the function what type does it return :(

quite disheartened you recommend go all auto :(

Read More »

Comment on GotW #90 Solution: Factories by Christophe

The fact that unique_ptr forces to know the destructor of the object forces to expose the class definition at each level (which is not the case with raw pointer, neither with shared_ptr), even when passing the unique_ptr through different layers. As a consequence that each time the class definition changes, it will imply the recompilation of those intermediate layers even if they do not really use the object. This tends to brake the usage of unique_ptr with factory.
Any comment about this ?

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by Jeffrey Bosboom

Expression templates are one thing you can’t use auto with, unless the proposed ‘operator auto()’ to suggest the type to convert to actually went somewhere.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by FJW

@Tom: exactly my thought. The knowledge of how these unpredictable "compiler, shut up!"-monsters are working is frightening.

Read More »

Comment on GotW #90 Solution: Factories by Herb Sutter

@Christophe: I have great news for you! That’s actually not a problem at all, because unique_ptr doesn’t need to know about the destructor — only the deleter does, which can be separately compiled. In fact, unique_ptr was explicitly designed to be usable with incomplete (forward-declared types), and the standard normatively requires: “The template parameter T of unique_ptr may be an incomplete type.” (N3690, 20.9.1 [unique_ptr] /5)

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by Herb Sutter

@Yuri: I agree. Updated, thanks.

@John: Good point, quick fix: 1L. :)

@Arne: Argh, that one gets me all the time. Fixed, thanks.

@Tom: Actually those are function-style casts, and for a non-aggregate type will call a constructor etc.

@rhalbersma: Yes, uint64_t and a few others are optional but they're in the standard and expected to be widely implemented so I used them. The "least" and "fast" ones are not optional, so if you don't have uint64_t you can use uint_least64_t or uint_fast64_t. … Okay, you've now convinced me to mention it. :) Added, mostly to note [1].

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by Nemanja Trifunovic

@pip010 In fact, there is a proposal to allow auto in function declarations as a return type: http://isocpp.org/blog/2013/04/n3638-return-type-deduction-for-normal-functions After that gets implemented, you will need to hunt not only for the declaration, but also for the implementation of the function.

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by cl22333

3. Should we use ‘auto’ when the variable is near critical points?(http://stackoverflow.com/questions/14081900/keyword-auto-near-critical-points)

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by mcmcc

Re: auto f5 = double{f1 + f2};

Is that statement identical to:

auto f5 = double{f1} + f2

?

I.e. in the second version, f2 must be promoted to higher precision before the add operation. In the first version, it seems the compiler might be compelled (allowed) to only do the promotion to double *after* the add, rendering the double promotion somewhat pointless.

Read More »

Comment on GotW #93 Solution: Auto Variables, Part 2 by John Smith

Using 0L is an improvement, but still does not quite fix it. For example, on 64-bit Windows long is still 32-bit, while void* and size_t is 64. The obvious solution would be to say “use 0ULL everywhere”, which would always be correct. However, this comes as a performance cost for tight loops, where index updates may now have to be done with a fairly high-latency add-with-carry. One solution which always works, but is *very* ugly, is

  for(auto i = v.size()*0; i < v.size(); i += 2)  

Read More »

Comment on GotW #94 Special Edition: AAA Style (Almost Always Auto) by bames53

1. It searches c for an object that compares equal to v and if it does not find one it constructs an element in place at the end of c using v.
2. It means to write code against intentional, public, specified guarantees. It’s beneficial because it means implementations can improve independently as long as the interface is maintained; bugs can be fixed, features can be added, all without unnecessary cascading code changes. Secondly because writing code that just seems to work but isn’t intentionally well specified can result in errors even without changes in the implementation, if the implementation isn’t well understood.
3. That the type won’t be statically specified; no, auto in C++ uses static type deduction. That the type will be hidden, making it difficult to understand code; possibly because interfaces might be specified in terms of specific types and a source editor might lack support for showing correctly deduced types.
4. a) The type of init can change without necessarily requiring the code using it to change in order to operate correctly. The possibility for an erroneous, silent implicit conversion is avoided. The initializer cannot be mistakenly omitted.
b) I don’t see any particular advantage to auto x = type{init}; vs. type x {init};.
5. a) Heap allocation syntax already explicity specifies types. Using auto x = make_unique(init); avoids duplication.
b) Literal suffixes also specify type and auto again avoids repeating it.
c) Lambda types are un-utterable and type deduction is required to get a named lambda.
d) formal parameters can have their types deduced from default values.
e) Type alias syntax using X = type;
6. auto declarations require the use of ‘inside-out’ syntax in order to add cv-qualifiers or to obtain reference types. You cannot use left-to-right type syntax, e.g. template using rref = T&&; rref x = f();. You must write: auto &&x = f();, or use explicit types: rref x = f(); or more verbose syntax using decltype.

Read More »
 
Delievered to you by Feedamail.
Unsubscribe

No comments:

Post a Comment