Wednesday, December 28, 2016

New ESDS Book: Effective SQL

SQL finally gets the effective treatment. That's an accomplishment, because despite an official ISO standard for SQL, there's enough variation among common offerings that the authors of Effective SQL felt obliged to test their code (e.g., schemas, queries, etc.) on six different implementations. They also point out syntactic and semantic differences between "official" SQL and the SQL you're probably using. 

Pulling off that kind of feat calls for lots of experience, both with SQL and with explaining it to others. Authors John Viescas, Doug Steele, and Ben Clothier have it in spades. They're pushing a century of IT experience (!), and they've published more than a half-dozen books on databases, SQL, or both. It's hard to get better than that.

If you work with SQL, you owe it to yourself to take a look at Effective SQL.

Scott

Tuesday, December 27, 2016

New ESDS Book: Effective C#, Third Edition

The third incarnation of Bill Wagner's best-selling Effective C# has flown off the presses, and a copy has landed on my desk. Apparently it's flying off the shelves, too, because it's currently Amazon's #1 new release in the category of Microsoft C and C++ Windows Programming. If you'd like the book to land on your desk as well as mine, you might want to place your order quickly.

This revision of Effective C# is part one of a two-park comprehensive update Bill is undertaking for both his C# titles (the other being More Effective C#). For details on the motivation for the updates and his thinking about them, check out Bill's recent blog post.

Happy C#ing!

Scott

Effective Modern C++ in Portuguese!

The latest addition to the Effective Modern C++ family goes by C++ Moderno e Eficaz and targets readers of Portuguese. My understanding is that the book's been out for a few months, but my copy arrived only a few days ago.

Like most foreign translations of EMC++, this one uses just one ink color, so if you're comfortable with technical English, I recommend the four-color English (American) edition. However, if Portuguese descriptions of C++11 and C++14 features is your preferred cup of tea, this is the brew for you!

Scott

Sunday, November 27, 2016

The Great Foreign Edition Book Giveaway

One of the nicer author perks is seeing your books appear in translation. In my 2003 Advice to Prospective Book Authors, I wrote:
Few things evoke quite the level of giddiness as seeing a copy of your book in a foreign script. I, for one, cherished my books in Chinese, and I continued to cherish them even after I found out that they were actually in Korean.
My publishers generally send me at least one copy of each translation they authorize. I often receive several copies, however, and over the years, I've amassed  more copies of my books in foreign languages than I have use for. Look!—these are the extra copies I currently have:

Instead of letting these books gather more dust, I've decided to give them away. Want one? Just ask. I'll autograph it for you and throw it in the mail, and all I'll request in return is that you cover the cost of postage.

I'll describe the details of how the giveaway works in a moment, but first let me show you the available inventory. Most books are in a language other than English, but what I'm technically giving away are foreign editions, so a few have the same text as the US book (i.e., they're in English). Such editions are generally printed on cheaper paper than their US counterparts, and like almost all the books I'm giving away, they use only one ink color, even if the US version uses multiple colors.

Here's what I've got:

Things to bear in mind:

  • For books with two ISBN lines, each line represents a distinct ISBN for the book. The upper one is the older ISBN-10. The lower one is the newer ISBN-13. (ISBN-10 vs ISBN-13 is the publishing equivalent of IPv4 vs. IPv6.)
  • Sometimes there are multiple versions of the same translation, e.g., there are two entries for German and for Japanese translations of Effective C++, Third Edition. In such cases, the only difference is typically the cover design. As far as I know, the substance of all translations of a particular book into a particular language is the same.
  • In the table, "Chinese" is ambiguous, because there are two versions of printed Chinese: traditional and simplified. To find out which Chinese is meant, use your favorite search engine to look up a book's ISBN.
  • I've tried to list accurate languages for the books, but, not being able to read most of them, I may have made a mistake here and there. If so, I apologize, and I hope you'll bring the errors to my attention.
  • The first two editions of Effective C++ are either old or really old. Both are out of date. They might be suitable for a C++ museum, or maybe you could employ them as research material for that Scott Meyers biography you've been working on (ahem), but the programming advice in these editions is not to be trusted. I'll send them to you if you ask me to, but before you make a request, think carefully about why you're doing it. It shouldn't be to improve your C++.

How the giveaway works:

  • If you'd like a book, send me email letting me know what you want and the address to which I should send it. If you'd like more than one book, that's fine, just list the books in priority order. (I'll ignore book requests posted as comments to this blog, sorry.)
  • I'll let the requests roll in for about two weeks (until about December 9), then I'll decide who gets what on whatever basis I want. My general plan is to assign higher priority to earlier requests and to issue everybody one book before issuing anybody more than one (i.e., to use a pseudo-FIFO pseudo-round-robin algorithm), but my plan might change. If your request includes an unusually good reason to satisfy it, I'll increase your priority. (An example of an unusually good reason would be that you'd like books to stock a library, thus making them available to many people.)
  • At some point (by December 16, I hope), I'll let you know whether I can satisfy your request. If I can, I'll put your book(s) in the mail, let you know how much the postage is, and request that you send me that much by Paypal. As it happens, I've gone down this road a couple of times in the past, and some of the promised payments never materialized. Nevertheless, my faith in the basic honesty of C++ software developers endures. I'd appreciate it if you wouldn't do anything to change that.
Soooo...who wants a book that I can't read, that's out of date, or both?

Scott

Monday, November 21, 2016

Help me sort out the meaning of "{}" as a constructor argument

In Effective Modern C++, one of the explanations I have in Item 7 ("Distinguish between () and {} when creating objects") is this:
If you want to call a std::initializer_list constructor with an empty std::initializer_list, you do it by making the empty braces a constructor argument—by putting the empty braces inside the parentheses or braces demarcating what you’re passing:
  
class Widget {
public:
  Widget();                                   // default ctor
  Widget(std::initializer_list<int> il);      // std::initializer_list ctor
  …                                           // no implicit conversion funcs
}; 

Widget w1;          // calls default ctor
Widget w2{};        // also calls default ctor
Widget w3();        // most vexing parse! declares a function!    

Widget w4({});      // calls std::initializer_list ctor with empty list
Widget w5{{}};      // ditto  
I recently got a bug report from Calum Laing saying that in his experience, the initializations of w4 and w5 aren't equivalent, because while w4 behaves as my comment indicates, the initialization of w5 takes place with a std::initializer_list with one element, not zero.

A little playing around showed that he was right, but further playing around showed that changing the example in small ways changed its behavior. In my pre-retirement-from-C++ days, that'd have been my cue to dive into the Standard to figure out what behavior was correct and, more importantly, why, but now that I'm supposed to be kicking back on tropical islands and downing piƱa coladas by the bucket (a scenario that would be more plausible if I laid around on beaches...or drank), I decided to stop my research at the point where things got complicated. "Use the force of the Internet!," I told myself. In that spirit, let me show you what I've got in the hope that you can tell me why I'm getting it. (Maybe it's obvious. I really haven't thought a lot about C++ since the end of last year.)

My experiments showed that one factor affecting whether "{{}}" as an argument list yields a zero-length std::initializer_list<T> was whether T had a default constructor, so I threw together some test code involving three classes, two of which could not be default-constructed. I then used both "({})" (note the outer parentheses) and "{{}}" as argument lists to a constructor taking a std::initializer_list for a template class imaginatively named X. When the constructor runs, it displays the number of elements in its std::initializer_list parameter.

Here's the code, where the comments in main show the results I got under all of gcc, clang, and vc++ at rextester.com.  Only one set of results is shown, because all three compilers produced the same output.
  
#include <iostream>
#include <initializer_list>

class DefCtor {
public:
  DefCtor(){}
};

class DeletedDefCtor {
public:
  DeletedDefCtor() = delete;
};

class NoDefCtor {
public:
  NoDefCtor(int){}
};

template<typename T>
class X {
public:
  X() { std::cout << "Def Ctor\n"; }
    
  X(std::initializer_list<T> il)
  {
    std::cout << "il.size() = " << il.size() << '\n';
  }
};

int main()
{
  X<DefCtor> a0({});           // il.size = 0
  X<DefCtor> b0{{}};           // il.size = 1
    
  X<DeletedDefCtor> a2({});    // il.size = 0
  X<DeletedDefCtor> b2{{}};    // il.size = 1

  X<NoDefCtor> a1({});         // il.size = 0
  X<NoDefCtor> b1{{}};         // il.size = 0
}
These results raise two questions:
  1. Why does the argument list syntax "{{}}" yield a one-element std::initializer_list for a type with a default constructor, but a zero-element std::initializer_list for a type with no default constructor?
  2. Why does a type with a deleted default constructor behave like a type with a default constructor instead of like a type with no default constructor?
If I change the example to declare DefCtor's constructor explicit, clang and vc++ produce code that yields a zero-length std::initializer_list, regardless of which argument list syntax is used:
class DefCtor {
public:
  explicit DefCtor(){}             // now explicit
};

...

X<DefCtor> a0({});           // il.size = 0
X<DefCtor> b0{{}};           // il.size = 0 (for clang and vc++)  
However, gcc rejects the code:
source_file.cpp:35:19: error: converting to ‘DefCtor’ from initializer list would use explicit constructor ‘DefCtor::DefCtor()’
   X<DefCtor> b0{{}};
                   ^
gcc's error message suggests that it may be trying to construct a DefCtor from an empty std::initializer_list in order to move-construct the resulting temporary into b0. If that's what it's trying to do, and if that's what compilers are supposed to do, the example would become more complicated, because it would mean that what I meant to be a series of single constructor calls may in fact include calls that create temporaries that are then used for move-constructions.

We thus have two new questions:
  1. Is the code valid if DefCtor's constructor is explicit?
  2. If so (i.e., if clang and vc++ are correct and gcc is incorrect), why does an explicit constructor behave differently from a non-explicit constructor in this example? The constructor we're dealing with doesn't take any arguments.
The natural next step would be to see what happens when we declare the constructors in DeletedDefCtor and/or NoDefCtor explicit, but my guess is that once we understand the answers to questions 1-4, we'll know enough to be able to anticipate (and verify) what would happen. I hereby open the floor to explanations of what's happening such that we can answer the questions I've posed. Please post your explanations in the comments!

---------- UPDATE ----------

As several commenters pointed out, in my code above, DeletedDefCtor is an aggregate, which is not what I intended. Here's revised code that eliminates that. With this revised code, all three compilers yield the same behavior, which, as noted in the comment in main below, includes failing to compile the initialization for b2. (Incidentally, I apologize for the 0-2-1 ordering of the variable names. They were originally in a different order, but I moved them around to make the example clearer, then forgot to rename them, thus rendering the example probably more confusing, sigh.)
  
#include <iostream>
#include <initializer_list>
 
class DefCtor {
  int x;
public:
  DefCtor(){}
};
 
class DeletedDefCtor {
  int x;
public:
  DeletedDefCtor() = delete;
};
 
class NoDefCtor {
  int x;    
public:
  NoDefCtor(int){}
};
 
template<typename T>
class X {
public:
  X() { std::cout << "Def Ctor\n"; }
     
  X(std::initializer_list<T> il)
  {
    std::cout << "il.size() = " << il.size() << '\n';
  }
};
 
int main()
{
  X<DefCtor> a0({});           // il.size = 0
  X<DefCtor> b0{{}};           // il.size = 1
     
  X<DeletedDefCtor> a2({});    // il.size = 0
  // X<DeletedDefCtor> b2{{}};    // error! attempt to use deleted constructor
 
  X<NoDefCtor> a1({});         // il.size = 0
  X<NoDefCtor> b1{{}};         // il.size = 0
}
This revised code renders question 2 moot.

The revised code exhibits the same behavior as the original code when DefCtor's constructor is declared explicit: gcc rejects the initialization of b0, but clang and vc++ accept it and, when the code is run, il.size() produces 0 (instead of the 1 that's produced when the constructor is not explicit).

---------- RESOLUTION ----------

Francisco Lopes, the first person to post comments on this blog post, described exactly what was happening as regards questions 1 and 2 about the original code I posted. The only thing he didn't do was cite sections of the Standard, which I can hardly fault him for. From my perspective, the key provisions in the C++14 Standard are
  • 13.3.1.7 ([over.match.list]), which says that when you have a braced initializer for an object, you first try to treat the entire initializer as an argument to a constructor taking a std::initializer_list. If that doesn't yield a valid call, you fall back on viewing the contents of the braced initializer as constructor arguments and perform overload resolution again.
and
  • 8.5.4/5 ([dcl.init.list]/5), which says that if you're initializing a std::initializer_list from a braced initializer, you copy-initialize each element of the std::initializer_list from the corresponding element of the braced initializer. The relevance of this part of the Standard was brought to my attention by Marco Alesiani in his comment below.
The behavior of the initializations of a0 and b0, then, can be explained as follows:
  
X<DefCtor> a0({});  // The arg list uses parens, not braces, so the only ctor argument is
                    // "{}", which, per 13.3.3.1.5/2 ([over.ics.list]/2) becomes an empty
                    // std::initializer_list. (Thanks to tcanens at reddit for the 
                    // reference to 13.3.3.1.5.)

X<DefCtor> b0{{}};  // The arg list uses braces, so the ctor argument is "{{}}", which is
                    // an initializer list with one element, "{}". DefCtor can be
                    // copy-initialized from "{}", so the ctor's std::initializer_list
                    // param contains a single default-constructed DefCtor object.
I thus understand the error in Effective Modern C++ that Calum Laing brought to my attention. The information in the comments (and in this reddit subthread) regarding how explicit constructors affect things is just a bonus.

Thanks to everybody for helping me understand what was going on. All I have to do now is figure out how to use this newfound understanding to fix the problem in the book...

Wednesday, November 9, 2016

Test Post -- Please Ignore

This is test content. Please ignore.

Monday, August 8, 2016

Interview with Me (in Korean)

My keynote address at NDC in Seoul got the Korean tech press interested in talking to me, and the interview Jihyun Lee conducted has now been published at Bloter.

As a rule, I read through my interviews before blogging about their existence, because, hey?!, who knows what I said? But since the interview is published in Korean, I skipped that step. If you read Korean as easily as you read C++, I hope you enjoy the interview. If you enjoy it enough to translate it into English (or if you find a translation floating around the Internet somewhere), please let me know.

Scott

Tuesday, June 21, 2016

Effective Modern C++ in Traditional Chinese!

Yesterday I received an interesting-looking box in the mail. The contents were even more interesting: the translation of Effective Modern C++ into Traditional Chinese!

This translation uses only one ink color (black), so if you're comfortable with technical English, you're probably better off with the English (American) edition.  If you prefer your C++ with a traditional Chinese flair, however, this new edition is the one for you.

EMC++ has now been translated into the following languages:
  • German
  • Italian
  • Polish
  • Japanese
  • Korean
  • Russian
  • French
  • Traditional Chinese
My understanding is that translations into Portuguese and Simplified Chinese are also in the works. If you're aware of other translations, please let me know.

In the meantime, enjoy the new Chinese translation of EMC++.

Scott

Monday, April 25, 2016

Thursday's NDC Presentation will be live, but remote

Recent developments have conspired to prevent me from attending this week's Nexon Developers Conference in Seoul, but I'll still be making my keynote presentation, "Modern C++ Beyond the Headlines." The talk will be live, but I'll be at home instead of in the conference hall. The heavy lifting on the communications front will be handled by Skype.

The keynote will take place at  5:05PM local time at the conference, which will be 1:05AM local time for me. It should be interesting to see who suffers more: the conference attendees at the end of a long day or me at the end of a longer one :-)

Scott

Monday, April 4, 2016

Presentation at Nexon Developers Conference in Seoul on April 28

In my "retirement from active involvement in C++" post at the end of last year, I wrote:
I may even give one more talk. (A potential conference appearance has been in the works for a while. If it gets scheduled, I'll let you know.)
Well, it's been scheduled, and I'm letting you know: I'll be giving a presentation at the Nexon Developers Conference in Seoul on April 28. The topic is "Modern C++ Beyond the Headlines," and I plan to talk about how some features in C++11/14 are better than they appear at first glance (e.g., constexpr), while others are likely to be less attractive than they initially seem (e.g., emplacement).

There are no talks in the pipeline after this one, and I've been holding fast on my decision not to accept new engagements, so in all likelihood, this is the last C++ presentation I'll make. If you want to be there to see if I botch the landing, the Nexon Developers Conference at the end of the month is the place to be!

Scott

Monday, March 28, 2016

Effective Modern C++ in French!

Et VoilĆ ! The French edition of Effective Modern C++ has just arrived at my desk, so it should be available for you, too.

This version of the book uses only one ink color (black), so if you're comfortable with technical English, I suspect you'll prefer the four-color English (American) edition. But if you like your C++ in French (including the code comments!), this new edition is your ami.

Scott